mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-07 05:21:12 +00:00
2997bb6292
Obviously the existing menu implementation from Duke Nukem needs to be tossed out at some point, but at least the functionality is there again.
251 lines
7.2 KiB
C++
251 lines
7.2 KiB
C++
//-----------------------------------------------------------------------------
|
|
//
|
|
// Copyright 1993-1996 id Software
|
|
// Copyright 1999-2016 Randy Heit
|
|
// Copyright 2002-2016 Christoph Oelckers
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
|
//
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "c_bind.h"
|
|
#include "d_event.h"
|
|
#include "d_gui.h"
|
|
#include "inputstate.h"
|
|
|
|
int eventhead;
|
|
int eventtail;
|
|
event_t events[NUM_EVENTS];
|
|
|
|
//==========================================================================
|
|
//
|
|
// G_Responder
|
|
// Process the event for the game
|
|
//
|
|
//==========================================================================
|
|
|
|
bool G_Responder (event_t *ev)
|
|
{
|
|
#if 0
|
|
// any other key pops up menu if in demos
|
|
// [RH] But only if the key isn't bound to a "special" command
|
|
if (gameaction == ga_nothing &&
|
|
(demoplayback || gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL))
|
|
{
|
|
const char *cmd = Bindings.GetBind (ev->data1);
|
|
|
|
if (ev->type == EV_KeyDown)
|
|
{
|
|
|
|
if (!cmd || (
|
|
strnicmp (cmd, "menu_", 5) &&
|
|
stricmp (cmd, "toggleconsole") &&
|
|
stricmp (cmd, "sizeup") &&
|
|
stricmp (cmd, "sizedown") &&
|
|
stricmp (cmd, "togglemap") &&
|
|
stricmp (cmd, "spynext") &&
|
|
stricmp (cmd, "spyprev") &&
|
|
stricmp (cmd, "chase") &&
|
|
stricmp (cmd, "+showscores") &&
|
|
stricmp (cmd, "bumpgamma") &&
|
|
stricmp (cmd, "screenshot")))
|
|
{
|
|
M_StartControlPanel(true);
|
|
M_SetMenu(NAME_Mainmenu, -1);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return C_DoKey (ev, &Bindings, &DoubleBindings);
|
|
}
|
|
}
|
|
if (cmd && cmd[0] == '+')
|
|
return C_DoKey (ev, &Bindings, &DoubleBindings);
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
if (gamestate == GS_LEVEL)
|
|
{
|
|
if (ST_Responder (ev))
|
|
return true; // status window ate it
|
|
if (!viewactive && primaryLevel->automap->Responder (ev, false))
|
|
return true; // automap ate it
|
|
}
|
|
else if (gamestate == GS_FINALE)
|
|
{
|
|
if (F_Responder (ev))
|
|
return true; // finale ate the event
|
|
}
|
|
#endif
|
|
|
|
switch (ev->type)
|
|
{
|
|
case EV_KeyDown:
|
|
if (C_DoKey (ev, &Bindings, &DoubleBindings))
|
|
return true;
|
|
break;
|
|
|
|
case EV_KeyUp:
|
|
C_DoKey (ev, &Bindings, &DoubleBindings);
|
|
break;
|
|
|
|
#if 0
|
|
// [RH] mouse buttons are sent as key up/down events
|
|
case EV_Mouse:
|
|
mousex = (int)(ev->x * mouse_sensitivity);
|
|
mousey = (int)(ev->y * mouse_sensitivity);
|
|
break;
|
|
#endif
|
|
}
|
|
|
|
// [RH] If the view is active, give the automap a chance at
|
|
// the events *last* so that any bound keys get precedence.
|
|
|
|
#if 0
|
|
if (gamestate == GS_LEVEL && viewactive && primaryLevel->automap)
|
|
return primaryLevel->automap->Responder (ev, true);
|
|
#endif
|
|
|
|
return (ev->type == EV_KeyDown ||
|
|
ev->type == EV_Mouse);
|
|
}
|
|
|
|
|
|
//==========================================================================
|
|
//
|
|
// D_ProcessEvents
|
|
//
|
|
// Send all the events of the given timestamp down the responder chain.
|
|
// Events are asynchronous inputs generally generated by the game user.
|
|
// Events can be discarded if no responder claims them
|
|
//
|
|
//==========================================================================
|
|
|
|
void D_ProcessEvents (void)
|
|
{
|
|
event_t *ev;
|
|
for (; eventtail != eventhead ; eventtail = (eventtail+1)&(NUM_EVENTS-1))
|
|
{
|
|
ev = &events[eventtail];
|
|
if (ev->type == EV_None)
|
|
continue;
|
|
if (ev->type == EV_DeviceChange)
|
|
(void)0;//UpdateJoystickMenu(I_UpdateDeviceList());
|
|
#if 0
|
|
if (C_Responder (ev))
|
|
continue; // console ate the event
|
|
if (M_Responder (ev))
|
|
continue; // menu ate the event
|
|
#endif
|
|
G_Responder (ev);
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// D_PostEvent
|
|
//
|
|
// Called by the I/O functions when input is detected.
|
|
//
|
|
//==========================================================================
|
|
void sendKeyForBinding(int key);
|
|
|
|
void D_PostEvent (const event_t *ev)
|
|
{
|
|
// Do not post duplicate consecutive EV_DeviceChange events.
|
|
if (ev->type == EV_DeviceChange && events[eventhead].type == EV_DeviceChange)
|
|
{
|
|
return;
|
|
}
|
|
events[eventhead] = *ev;
|
|
#if 0 // No idea if this can be made to work ever... For now, pass on the mouse movement event so that the input code can deal with them itself.
|
|
if (ev->type == EV_Mouse && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling && !primaryLevel->localEventManager->Responder(ev) && !paused)
|
|
{
|
|
if (Button_Mlook.bDown || freelook)
|
|
{
|
|
int look = int(ev->y * m_pitch * mouse_sensitivity * 16.0);
|
|
if (invertmouse)
|
|
look = -look;
|
|
G_AddViewPitch (look, true);
|
|
events[eventhead].y = 0;
|
|
}
|
|
if (!Button_Strafe.bDown && !lookstrafe)
|
|
{
|
|
G_AddViewAngle (int(ev->x * m_yaw * mouse_sensitivity * 8.0), true);
|
|
events[eventhead].x = 0;
|
|
}
|
|
if ((events[eventhead].x | events[eventhead].y) == 0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if ((GUICapture & 8) && ev->type == EV_KeyDown)
|
|
{
|
|
// This must bypass the entire event management
|
|
sendKeyForBinding(ev->data1);
|
|
return;
|
|
}
|
|
|
|
// Add the key to the global keyboard state.
|
|
// This is probably the biggest roadblock with the input system as it undermines a proper event driven approach.
|
|
// Too much code depends on just checking this instead of waiting for events to happen.
|
|
// Here's also definitely not the best place to maintain the keyboard state but right now it's unavoidable to do this outside the event processing because so much code depends on it.
|
|
// Once all those busy waiting loops can poll the event queue for a proper skip event, this will mostly go away.
|
|
inputState.AddEvent(ev);
|
|
|
|
// Also add it to the event queue - this is where everything should transition to eventually.
|
|
eventhead = (eventhead+1)&(NUM_EVENTS-1);
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// D_RemoveNextCharEvent
|
|
//
|
|
// Removes the next EV_GUI_Char event in the input queue. Used by the menu,
|
|
// since it (generally) consumes EV_GUI_KeyDown events and not EV_GUI_Char
|
|
// events, and it needs to ensure that there is no left over input when it's
|
|
// done. If there are multiple EV_GUI_KeyDowns before the EV_GUI_Char, then
|
|
// there are dead chars involved, so those should be removed, too. We do
|
|
// this by changing the message type to EV_None rather than by actually
|
|
// removing the event from the queue.
|
|
//
|
|
//==========================================================================
|
|
|
|
void D_RemoveNextCharEvent()
|
|
{
|
|
assert(events[eventtail].type == EV_GUI_Event && events[eventtail].subtype == EV_GUI_KeyDown);
|
|
for (int evnum = eventtail; evnum != eventhead; evnum = (evnum+1) & (NUM_EVENTS-1))
|
|
{
|
|
event_t *ev = &events[evnum];
|
|
if (ev->type != EV_GUI_Event)
|
|
break;
|
|
if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_Char)
|
|
{
|
|
ev->type = EV_None;
|
|
if (ev->subtype == EV_GUI_Char)
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|