- console output is functional.

This commit is contained in:
Christoph Oelckers 2019-11-06 23:40:10 +01:00
parent 81e9c867da
commit b6a3a60251
36 changed files with 116 additions and 85 deletions

View file

@ -22,7 +22,7 @@ extern "C"
#endif // _WIN32
int32_t g_borderless=2;
bool GUICapture = false;
int GUICapture = false;
// input
char inputdevices = 0;

View file

@ -22,6 +22,8 @@
#include "scriptfile.h"
#include "softsurface.h"
#include "gamecvars.h"
#include "c_console.h"
#include "v_2ddrawer.h"
#ifdef USE_OPENGL
# include "glsurface.h"
@ -10422,6 +10424,7 @@ void videoNextPage(void)
if (in3dmode())
{
// software rendering only
videoBeginDrawing(); //{{{
for (bssize_t i=permtail; i!=permhead; i=((i+1)&(MAXPERMS-1)))
{
@ -10433,10 +10436,13 @@ void videoNextPage(void)
}
videoEndDrawing(); //}}}
//OSD_Draw();
videoShowFrame(0);
C_DrawConsole();
GLInterface.Draw2D(&twod);
videoBeginDrawing(); //{{{
videoShowFrame(0);
// software rendering only
videoBeginDrawing(); //{{{
for (bssize_t i=permtail; i!=permhead; i=((i+1)&(MAXPERMS-1)))
{
per = &permfifo[i];

View file

@ -35,6 +35,8 @@ int timerInit(int const tickspersecond)
return 0;
}
TArray<void(*)(void)> callbacks;
ATTRIBUTE((flatten)) void timerUpdateClock(void)
{
auto time = steady_clock::now();
@ -50,16 +52,14 @@ ATTRIBUTE((flatten)) void timerUpdateClock(void)
totalclock += n;
timerlastsample += n*nanoseconds(1000000000/timerticspersec);
if (usertimercallback)
for (; n > 0; n--) usertimercallback();
for (; n > 0; n--)
{
for (auto cb : callbacks) cb();
}
}
void(*timerSetCallback(void(*callback)(void)))(void)
{
void(*oldtimercallback)(void);
oldtimercallback = usertimercallback;
usertimercallback = callback;
return oldtimercallback;
callbacks.Push(callback);
return nullptr;
}

View file

@ -100,7 +100,8 @@ void DrawChar (F2DDrawer* drawer, FFont *font, int normalcolor, double x, double
{
return;
}
PalEntry color = 0xffffffff;
PalEntry color ;
parms.remap = font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255);
drawer->AddTexture(pic, parms);
}
@ -126,7 +127,6 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
double cx;
double cy;
int boldcolor;
int range;
int kerning;
FTexture *pic;
@ -139,7 +139,7 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
PalEntry colorparm = parms.color;
PalEntry color = 0xffffffff;
range = font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.remap = font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.color = PalEntry(colorparm.a, (color.r * colorparm.r) / 255, (color.g * colorparm.g) / 255, (color.b * colorparm.b) / 255);
kerning = font->GetDefaultKerning();
@ -166,7 +166,7 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
EColorRange newcolor = V_ParseFontColor(ch, normalcolor, boldcolor);
if (newcolor != CR_UNDEFINED)
{
range = font->GetColorTranslation(newcolor, &color);
parms.remap = font->GetColorTranslation(newcolor, &color);
parms.color = PalEntry(colorparm.a, (color.r * colorparm.r) / 255, (color.g * colorparm.g) / 255, (color.b * colorparm.b) / 255);
currentcolor = newcolor;
}

View file

@ -52,6 +52,7 @@
#include "v_draw.h"
#include "v_font.h"
#include "printf.h"
#include "inputstate.h"
#define LEFTMARGIN 8
@ -634,6 +635,8 @@ void C_InitConsole (int width, int height, bool ingame)
ConCols = ConWidth / cwidth;
if (conbuffer == NULL) conbuffer = new FConsoleBuffer;
timerSetCallback(C_Ticker);
}
//==========================================================================
@ -1011,6 +1014,11 @@ void C_NewModeAdjust ()
int consoletic = 0;
void C_Ticker()
{
// The engine timer ticks at 120 fps which is 4x too fast for this.
static int delay = 0;
if (++delay < 4) return;
delay = 0;
static int lasttic = 0;
consoletic++;
@ -1193,7 +1201,6 @@ void C_DrawConsole ()
else
{
PalEntry pe((uint8_t)(con_alpha * 255), 0, 0, 0);
0, (/*gamestate != GS_FULLCONSOLE*/true) ? (double)con_alpha : 1,
twod.AddColorOnlyQuad(0, 0, screen->GetWidth(), visheight, pe);
}
if (conline && visheight < screen->GetHeight())
@ -1319,11 +1326,13 @@ void C_ToggleConsole ()
HistPos = NULL;
TabbedLast = false;
TabbedList = false;
GUICapture++;
}
else //if (gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP)
{
ConsoleState = c_rising;
C_FlushDisplay ();
GUICapture--;
}
}
@ -1768,6 +1777,11 @@ CCMD (echo)
}
}
CCMD(toggleconsole)
{
C_ToggleConsole();
}
#if 0 // The Build engine cannot do this at the moment. Q: Implement and redirect some messages here?
/* Printing in the middle of the screen */

View file

@ -390,7 +390,7 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
remap.Palette[0] = 0;
for (j = 0; j < ActiveColors; j++)
for (j = 1; j < ActiveColors; j++)
{
int v = int(luminosity[j] * 256.0);

View file

@ -88,7 +88,7 @@ struct HexDataSource
static HexDataSource hexdata;
// This is a font character that reads RLE compressed data.
class FHexFontChar : public FTexture
class FHexFontChar : public FTileTexture
{
public:
FHexFontChar(uint8_t *sourcedata, int swidth, int width, int height);

View file

@ -11,7 +11,7 @@
extern char appactive;
typedef uint8_t kb_scancode;
extern bool GUICapture;
extern int GUICapture;
// This encapsulates the entire game-readable input state which previously was spread out across several files.

View file

@ -6488,7 +6488,7 @@ MAIN_LOOP_RESTART:
int const moveClock = (int)totalclock;
if (((ud.show_help == 0 && (myplayer.gm & MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1))
if (((ud.show_help == 0 && !GUICapture && (myplayer.gm & MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1))
&& (myplayer.gm & MODE_GAME))
{
G_MoveLoop();

View file

@ -61,18 +61,25 @@ PaletteManager::~PaletteManager()
//
//===========================================================================
void PaletteManager::DeleteAll()
void PaletteManager::DeleteAllTextures()
{
for (auto& pal : palettes)
{
if (pal.paltexture) delete pal.paltexture;
pal.paltexture = nullptr;
}
for (auto& pal : palswaps)
{
if (pal.swaptexture) delete pal.swaptexture;
pal.swaptexture = nullptr;
}
if (palswapTexture) delete palswapTexture;
palswapTexture = nullptr;
}
void PaletteManager::DeleteAll()
{
DeleteAllTextures();
palettes.Reset();
palswaps.Reset();
lastindex = ~0u;
@ -144,7 +151,7 @@ unsigned PaletteManager::FindPalswap(const uint8_t* paldata)
for (int i = 0; i < 255; i++)
{
int map = paldata[i];
PalEntry color = palettes[0].colors[map];
PalEntry color = palettes[palettemap[0]].colors[map];
if (color.Luminance() < foundColor.Luminance())
{
foundColor = color;
@ -154,7 +161,7 @@ unsigned PaletteManager::FindPalswap(const uint8_t* paldata)
// Determine the fade color. We pick what black, or the darkest color, maps to in the lowest shade level.
int map = paldata[(numshades - 2) * 256 + found]; // do not look in the latest shade level because it doesn't always contain useful data for this.
pd.fadeColor = palettes[0].colors[map];
pd.fadeColor = palettes[palettemap[0]].colors[map];
if (pd.fadeColor.Luminance() < 10) pd.fadeColor = 0; // Account for the inability to check the last fade level by using a higher threshold for determining black fog.
return palswaps.Push(pd);

View file

@ -171,7 +171,7 @@ void GLInstance::Deinit()
if (vpxShader) delete vpxShader;
vpxShader = nullptr;
activeShader = nullptr;
palmanager.DeleteAll();
palmanager.DeleteAllTextures();
lastPalswapIndex = -1;
}
@ -210,14 +210,23 @@ void GLInstance::Draw(EDrawType type, size_t start, size_t count)
renderState.Apply(polymostShader);
if (renderState.VertexBuffer != LastVertexBuffer || LastVB_Offset[0] != renderState.VB_Offset[0] || LastVB_Offset[1] != renderState.VB_Offset[1])
{
static_cast<OpenGLRenderer::GLVertexBuffer*>(renderState.VertexBuffer)->Bind(renderState.VB_Offset);
if (renderState.VertexBuffer)
{
static_cast<OpenGLRenderer::GLVertexBuffer*>(renderState.VertexBuffer)->Bind(renderState.VB_Offset);
}
else glBindBuffer(GL_ARRAY_BUFFER, 0);
LastVertexBuffer = renderState.VertexBuffer;
LastVB_Offset[0] = renderState.VB_Offset[0];
LastVB_Offset[1] = renderState.VB_Offset[1];
}
if (renderState.IndexBuffer != LastIndexBuffer)
{
static_cast<OpenGLRenderer::GLIndexBuffer*>(renderState.IndexBuffer)->Bind();
if (renderState.IndexBuffer)
{
static_cast<OpenGLRenderer::GLIndexBuffer*>(renderState.IndexBuffer)->Bind();
}
else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
LastIndexBuffer = renderState.IndexBuffer;
}
}
if (!LastVertexBuffer)

View file

@ -16,6 +16,7 @@ class PolymostShader;
class SurfaceShader;
class FTexture;
class GLInstance;
class F2DDrawer;
struct PaletteData
{
@ -72,6 +73,7 @@ public:
{}
~PaletteManager();
void DeleteAll();
void DeleteAllTextures();
void SetPalette(int index, const uint8_t *data);
void SetPalswapData(int index, const uint8_t* data, int numshades);
@ -215,6 +217,7 @@ public:
void LoadPolymostShader();
void LoadSurfaceShader();
void LoadVPXShader();
void Draw2D(F2DDrawer* drawer);
void Deinit();

View file

@ -82,17 +82,18 @@ public:
//
//===========================================================================
void Draw2D(F2DDrawer *drawer, FRenderState &state)
void GLInstance::Draw2D(F2DDrawer *drawer)
{
VSMatrix mat(0);
GLInterface.SetMatrix(Matrix_View, mat.get());
GLInterface.SetMatrix(Matrix_ModelView, mat.get());
GLInterface.SetMatrix(Matrix_Detail, mat.get());
SetMatrix(Matrix_View, mat.get());
SetMatrix(Matrix_ModelView, mat.get());
SetMatrix(Matrix_Detail, mat.get());
mat.ortho(0, xdim, ydim, 0, -1, 1);
GLInterface.SetMatrix(Matrix_Projection, mat.get());
GLInterface.SetViewport(0, 0, xdim, ydim);
GLInterface.EnableDepthTest(false);
GLInterface.EnableMultisampling(false);
SetMatrix(Matrix_Projection, mat.get());
SetViewport(0, 0, xdim, ydim);
EnableDepthTest(false);
EnableMultisampling(false);
EnableBlend(true);
auto &vertices = drawer->mVertices;
auto &indices = drawer->mIndices;
@ -113,9 +114,9 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
}
F2DVertexBuffer vb;
vb.UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size());
GLInterface.SetVertexBuffer(vb.GetBufferObjects().first, 0, 0);
GLInterface.SetIndexBuffer(vb.GetBufferObjects().second);
GLInterface.SetFadeDisable(true);
SetVertexBuffer(vb.GetBufferObjects().first, 0, 0);
SetIndexBuffer(vb.GetBufferObjects().second);
SetFadeDisable(true);
for(auto &cmd : commands)
{
@ -139,37 +140,37 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
{
sciX = sciY = sciW = sciH = -1;
}
//GLInterface.SetScissor(sciX, sciY, sciW, sciH);
//SetScissor(sciX, sciY, sciW, sciH);
//state.SetFog(cmd.mColor1, 0);
GLInterface.SetColor(1, 1, 1);
SetColor(1, 1, 1);
//state.SetColor(1, 1, 1, 1, cmd.mDesaturate);
GLInterface.SetAlphaThreshold(0.0f);
SetAlphaThreshold(0.0f);
if (cmd.mTexture != nullptr)
{
auto tex = cmd.mTexture;
GLInterface.SetNamedTexture(cmd.mTexture, cmd.mRemapIndex, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
GLInterface.UseColorOnly(false);
SetNamedTexture(cmd.mTexture, cmd.mRemapIndex, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
UseColorOnly(false);
}
else
{
GLInterface.UseColorOnly(true);
UseColorOnly(true);
}
switch (cmd.mType)
{
case F2DDrawer::DrawTypeTriangles:
GLInterface.Draw(DT_TRIANGLES, cmd.mIndexIndex, cmd.mIndexCount);
Draw(DT_TRIANGLES, cmd.mIndexIndex, cmd.mIndexCount);
break;
case F2DDrawer::DrawTypeLines:
GLInterface.Draw(DT_LINES, cmd.mVertIndex, cmd.mVertCount);
//Draw(DT_LINES, cmd.mVertIndex, cmd.mVertCount);
break;
case F2DDrawer::DrawTypePoints:
//GLInterface.Draw(DT_POINTS, cmd.mVertIndex, cmd.mVertCount);
//Draw(DT_POINTS, cmd.mVertIndex, cmd.mVertCount);
break;
}
@ -185,12 +186,13 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
//state.SetScissor(-1, -1, -1, -1);
//state.SetRenderStyle(STYLE_Translucent);
GLInterface.SetVertexBuffer(nullptr, 0, 0);
GLInterface.SetIndexBuffer(nullptr);
GLInterface.UseColorOnly(false);
SetVertexBuffer(nullptr, 0, 0);
SetIndexBuffer(nullptr);
UseColorOnly(false);
//state.EnableBrightmap(true);
//state.SetTextureMode(TM_NORMAL);
GLInterface.SetFadeDisable(false);
GLInterface.SetColor(1, 1, 1);
SetFadeDisable(false);
SetColor(1, 1, 1);
//drawer->mIsFirstPass = false;
twod.Clear();
}

View file

@ -7896,7 +7896,7 @@ MAIN_LOOP_RESTART:
int const moveClock = (int) totalclock;
if (((ud.show_help == 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1)) &&
if (((ud.show_help == 0 && !GUICapture && (g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU) || ud.recstat == 2 || (g_netServer || ud.multimode > 1)) &&
(g_player[myconnectindex].ps->gm&MODE_GAME))
{
G_MoveLoop();

View file

@ -683,14 +683,11 @@ SWBOOL MNU_KeySetupCustom(UserCall call, MenuItem *item)
inputState.ClearKeyStatus(inputState.GetLastScanCode());
//KeyboardKeys[currentkey][currentcol] = KB_GetLastScanCode();
if (currentkey != gamefunc_Show_Console)
{
#if 0 // [JM] Re-do this shit !CHECKME!
CONTROL_MapKey(currentkey,
KeyboardKeys[currentkey][0],
KeyboardKeys[currentkey][1]);
#endif
}
currentmode = 0;
}
@ -733,10 +730,7 @@ SWBOOL MNU_KeySetupCustom(UserCall call, MenuItem *item)
else if (inputState.GetKeyStatus(sc_Delete))
{
inputState.ClearKeyStatus(sc_Delete);
if (currentkey != gamefunc_Show_Console)
{
//Bindings.UnbindACommand(buttonMap.GetButtonName(M_KEYBOARDKEYS.currentEntry));
}
//Bindings.UnbindACommand(buttonMap.GetButtonName(M_KEYBOARDKEYS.currentEntry));
}
else if (inputState.GetKeyStatus(sc_Home))
{
@ -787,8 +781,6 @@ SWBOOL MNU_KeySetupCustom(UserCall call, MenuItem *item)
currentcol = 0;
}
if (currentkey == gamefunc_Show_Console) currentcol = 0;
CONTROL_ClearUserInput(&inpt);
if (NUMGAMEFUNCTIONS > PGSIZ)
@ -827,8 +819,6 @@ SWBOOL MNU_KeySetupCustom(UserCall call, MenuItem *item)
MNU_DrawSmallString(OPT_XSIDE, j, p, (i==currentkey) ? -5 : 12,
(i==currentkey && currentcol==0) ? 14 : 16);
if (i == gamefunc_Show_Console) continue;
p = keyGetName(KeyboardKeys[i][1]);
if (!p || KeyboardKeys[i][1]==0xff) p = " -";
MNU_DrawSmallString(OPT_XSIDE + 4*14, j, p, (i==currentkey) ? -5 : 12,

View file

@ -68,7 +68,7 @@ J "+JumpBoots"
M "+MedKit"
P "+ProximityBombs"
R "+RemoteBombs"
` "+Show_Console"
` "toggleconsole"
Mouse1 "+Fire"
Mouse2 "+Alt_Fire"
MWheelUp "+Previous_Weapon"

View file

@ -64,7 +64,7 @@ J "+JumpBoots"
M "+MedKit"
P "+ProximityBombs"
R "+RemoteBombs"
` "+Show_Console"
` "toggleconsole"
Mouse1 "+Fire"
Mouse2 "+Open"
Mouse3 "+Run"

View file

@ -69,7 +69,7 @@ J "+JumpBoots"
M "+MedKit"
P "+ProximityBombs"
R "+RemoteBombs"
` "+Show_Console"
` "toggleconsole"
Mouse1 "+Fire"
Mouse2 "+Alt_Fire"
MWheelUp "+Previous_Weapon"

View file

@ -63,7 +63,7 @@ R "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
X "+Last_Used_Weapon"
F6 "+Quick_Save"

View file

@ -59,7 +59,7 @@ R "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"

View file

@ -66,7 +66,7 @@ R "+Steroids"
` "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
C "+Show_Console"
C "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"

View file

@ -57,7 +57,7 @@ F "+Map_Follow_Mode"
K "+See_Coop_View"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
X "+Last_Used_Weapon"
F6 "+Quick_Save"

View file

@ -57,7 +57,7 @@ U "+Mouse_Aiming"
I "+Toggle_Crosshair"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"

View file

@ -60,7 +60,7 @@ U "+Mouse_Aiming"
I "+Toggle_Crosshair"
' "+Next_Weapon"
; "+Previous_Weapon"
C "+Show_Console"
C "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"

View file

@ -63,7 +63,7 @@ R "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
X "+Last_Used_Weapon"
F6 "+Quick_Save"

View file

@ -63,7 +63,7 @@ R "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"

View file

@ -66,7 +66,7 @@ R "+Steroids"
` "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
C "+Show_Console"
C "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"

View file

@ -64,7 +64,7 @@ M "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
+ "+Dpad_Select"
X "+Last_Used_Weapon"
F6 "+Quick_Save"

View file

@ -63,7 +63,7 @@ M "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
F6 "+Quick_Save"
F9 "+Quick_Load"
F7 "+Third_Person_View"

View file

@ -68,7 +68,7 @@ M "+Steroids"
` "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
V "+Show_Console"
V "toggleconsole"
F6 "+Quick_Save"
F9 "+Quick_Load"
F7 "+Third_Person_View"

View file

@ -36,7 +36,7 @@ F "+Map_Follow_Mode"
K "+See_Coop_View"
U "+Mouse_Aiming"
I "+Toggle_Crosshair"
` "+Show_Console"
` "toggleconsole"
Mouse1 "+Fire"
Mouse2 "+MediKit"
MWheelUp "+Previous_Weapon"

View file

@ -58,7 +58,7 @@ U "+Mouse_Aiming"
I "+Toggle_Crosshair"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Mouse1 "+Fire"
Mouse2 "+Open"
Mouse3 "+Run"

View file

@ -63,7 +63,7 @@ U "+Mouse_Aiming"
I "+Toggle_Crosshair"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Mouse1 "+Fire"
Mouse2 "+MediKit"
MWheelUp "+Previous_Weapon"

View file

@ -63,7 +63,7 @@ R "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
X "+Last_Used_Weapon"
F6 "+Quick_Save"

View file

@ -64,7 +64,7 @@ R "+Steroids"
Q "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
` "+Show_Console"
` "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"

View file

@ -67,7 +67,7 @@ R "+Steroids"
` "+Quick_Kick"
' "+Next_Weapon"
; "+Previous_Weapon"
C "+Show_Console"
C "toggleconsole"
Capslock "+AutoRun"
F6 "+Quick_Save"
F9 "+Quick_Load"