Skip to content

Commit

Permalink
Fixed a problem with game controls being active while in the control …
Browse files Browse the repository at this point in the history
…panel.

The following changes were made:

- A "deui" binding context was added as the topmost one, with a new flag (Acquire All) that acquires all existing devices for the context.

- However, since that doesn't cover the case where no one is requesting the current value for an axis (e.g., while in the control panel), the function I_DeviceReset() was added to clear the relative accumulation of the device's axes. This gets called when the UI mode ends (always called when a context with the Acquire All flag is deactivated).

- When quitting via the menu, the deui binding context gets activated to prevent the player from looking around during the countdown.
  • Loading branch information
skyjake committed Jan 17, 2009
1 parent 03802c6 commit 7549616
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 6 deletions.
2 changes: 2 additions & 0 deletions doomsday/engine/portable/include/b_context.h
Expand Up @@ -46,6 +46,7 @@ typedef struct controlbinding_s {
#define BCF_PROTECTED 0x02 // Context cannot be
#define BCF_ACQUIRE_KEYBOARD 0x04 // Context has acquired all keyboard states, unless
// higher-priority contexts override it.
#define BCF_ACQUIRE_ALL 0x08 // Context will acquire all unacquired states.

typedef struct bclass_s {
char* name; // Name of the binding context.
Expand All @@ -59,6 +60,7 @@ bcontext_t* B_NewContext(const char* name);
void B_DestroyAllContexts(void);
void B_ActivateContext(bcontext_t* bc, boolean doActivate);
void B_AcquireKeyboard(bcontext_t* bc, boolean doAcquire);
void B_AcquireAll(bcontext_t* bc, boolean doAcquire);
bcontext_t* B_ContextByPos(int pos);
bcontext_t* B_ContextByName(const char* name);
int B_ContextCount(void);
Expand Down
5 changes: 3 additions & 2 deletions doomsday/engine/portable/include/b_main.h
Expand Up @@ -29,8 +29,9 @@
#ifndef __DOOMSDAY_BIND_MAIN_H__
#define __DOOMSDAY_BIND_MAIN_H__

#define DEFAULT_BINDING_CONTEXT_NAME "game"
#define CONSOLE_BINDING_CONTEXT_NAME "console"
#define DEFAULT_BINDING_CONTEXT_NAME "game"
#define CONSOLE_BINDING_CONTEXT_NAME "console"
#define UI_BINDING_CONTEXT_NAME "deui"

void B_Register(void);
void B_Init(void);
Expand Down
1 change: 1 addition & 0 deletions doomsday/engine/portable/include/dd_input.h
Expand Up @@ -177,6 +177,7 @@ byte DD_ModKey(byte key);
void I_InitVirtualInputDevices(void);
void I_ShutdownInputDevices(void);
void I_ClearDeviceContextAssociations(void);
void I_DeviceReset(uint ident);
inputdev_t *I_GetDevice(uint ident, boolean ifactive);
inputdev_t *I_GetDeviceByName(const char *name, boolean ifactive);
boolean I_ParseDeviceAxis(const char *str, uint *deviceID, uint *axis);
Expand Down
45 changes: 45 additions & 0 deletions doomsday/engine/portable/src/b_context.c
Expand Up @@ -193,6 +193,34 @@ void B_UpdateDeviceStateAssociations(void)
dev->keys[k].bContext = bc;
}
}

if(bc->flags & BCF_ACQUIRE_ALL)
{
int j;
for(j = 0; j < NUM_INPUT_DEVICES; ++j)
{
inputdev_t* dev = I_GetDevice(j, true);

if(!dev)
continue;

for(k = 0; k < dev->numKeys; ++k)
{
if(!dev->keys[k].bContext)
dev->keys[k].bContext = bc;
}
for(k = 0; k < dev->numAxes; ++k)
{
if(!dev->axes[k].bContext)
dev->axes[k].bContext = bc;
}
for(k = 0; k < dev->numHats; ++k)
{
if(!dev->hats[k].bContext)
dev->hats[k].bContext = bc;
}
}
}
}
}

Expand Down Expand Up @@ -272,6 +300,15 @@ void B_ActivateContext(bcontext_t* bc, boolean doActivate)
if(doActivate)
bc->flags |= BCF_ACTIVE;
B_UpdateDeviceStateAssociations();

if(bc->flags & BCF_ACQUIRE_ALL)
{
int i;
for(i = 0; i < NUM_INPUT_DEVICES; ++i)
{
I_DeviceReset(i);
}
}
}

void B_AcquireKeyboard(bcontext_t* bc, boolean doAcquire)
Expand All @@ -282,6 +319,14 @@ void B_AcquireKeyboard(bcontext_t* bc, boolean doAcquire)
B_UpdateDeviceStateAssociations();
}

void B_AcquireAll(bcontext_t* bc, boolean doAcquire)
{
bc->flags &= ~BCF_ACQUIRE_ALL;
if(doAcquire)
bc->flags |= BCF_ACQUIRE_ALL;
B_UpdateDeviceStateAssociations();
}

bcontext_t* B_ContextByName(const char* name)
{
int i;
Expand Down
39 changes: 36 additions & 3 deletions doomsday/engine/portable/src/b_device.c
Expand Up @@ -232,6 +232,28 @@ dbinding_t* B_NewDeviceBinding(dbinding_t* listRoot, const char* deviceDesc)
return cb;
}

dbinding_t* B_FindDeviceBinding(bcontext_t* context, uint device, cbdevtype_t bindType, int id)
{
controlbinding_t* cb;
dbinding_t* d;
int i;

for(cb = context->controlBinds.next; cb != &context->controlBinds; cb = cb->next)
{
for(i = 0; i < DDMAXPLAYERS; ++i)
{
for(d = cb->deviceBinds[i].next; d != &cb->deviceBinds[i]; d = d->next)
{
if(d->device == device && d->type == bindType && d->id == id)
{
return d;
}
}
}
}
return NULL;
}

void B_DestroyDeviceBinding(dbinding_t* cb)
{
if(cb)
Expand Down Expand Up @@ -304,10 +326,21 @@ void B_EvaluateDeviceBindingList(dbinding_t* listRoot, float* pos, float* relati
break;

case CBD_AXIS:
if(controlClass && dev->axes[cb->id].bContext != controlClass)
continue; // Shadowed by a more important active class.

axis = &dev->axes[cb->id];
if(controlClass && axis->bContext != controlClass)
{
if(!B_FindDeviceBinding(axis->bContext, cb->device, CBD_AXIS, cb->id))
{
// The overriding context doesn't bind to the axis, though.
if(axis->type == IDAT_POINTER)
{
// Reset the relative accumulation.
axis->position = 0;
}
}
continue; // Shadowed by a more important active class.
}

if(axis->type == IDAT_POINTER)
{
deviceOffset = axis->position;
Expand Down
3 changes: 3 additions & 0 deletions doomsday/engine/portable/src/b_main.c
Expand Up @@ -196,6 +196,9 @@ void B_Init(void)
bc = B_NewContext(CONSOLE_BINDING_CONTEXT_NAME);
bc->flags |= BCF_PROTECTED; // Only we can (de)activate.
B_AcquireKeyboard(bc, true); // Console takes over all keyboard events.

// UI doesn't let anything past it.
B_AcquireAll(B_NewContext(UI_BINDING_CONTEXT_NAME), true);
/*
B_BindCommand("joy-hat-angle3", "print {angle 3}");
B_BindCommand("joy-hat-center", "print center");
Expand Down
15 changes: 15 additions & 0 deletions doomsday/engine/portable/src/dd_input.c
Expand Up @@ -277,6 +277,21 @@ void I_ShutdownInputDevices(void)
}
}

void I_DeviceReset(uint ident)
{
inputdev_t* dev = &inputDevices[ident];
int k;

for(k = 0; k < dev->numAxes; ++k)
{
if(dev->axes[k].type == IDAT_POINTER)
{
// Clear the accumulation.
dev->axes[k].position = 0;
}
}
}

/**
* Retrieve a pointer to the input device state by identifier.
*
Expand Down
4 changes: 4 additions & 0 deletions doomsday/engine/portable/src/ui_main.c
Expand Up @@ -151,6 +151,7 @@ void UI_Init(boolean halttime, boolean tckui, boolean tckframe, boolean drwgame,
return;

uiActive = true;
B_ActivateContext(B_ContextByName(UI_BINDING_CONTEXT_NAME), true);

// Restore full alpha.
uiAlpha = uiTargetAlpha = 1.0;
Expand Down Expand Up @@ -187,10 +188,13 @@ void UI_Init(boolean halttime, boolean tckui, boolean tckframe, boolean drwgame,
void UI_End(void)
{
ddevent_t rel;
int i;

if(!uiActive)
return;
uiActive = false;

B_ActivateContext(B_ContextByName(UI_BINDING_CONTEXT_NAME), false);

// Restore full alpha.
uiAlpha = uiTargetAlpha = 1.0;
Expand Down
2 changes: 1 addition & 1 deletion doomsday/plugins/common/src/hu_menu.c
Expand Up @@ -3378,7 +3378,7 @@ int M_QuitResponse(msgresponse_t response, void* context)
S_LocalSound(quitsounds[((int)GAMETIC >> 2) & 7], NULL);

// Wait for 1.5 seconds.
DD_Executef(true, "after 53 quit!");
DD_Executef(true, "activatebcontext deui; after 53 quit!");
quitYet = true;
}
}
Expand Down

0 comments on commit 7549616

Please sign in to comment.