diff --git a/doomsday/engine/portable/include/b_util.h b/doomsday/engine/portable/include/b_util.h index 67604ce894..cb7ae4b348 100644 --- a/doomsday/engine/portable/include/b_util.h +++ b/doomsday/engine/portable/include/b_util.h @@ -74,6 +74,7 @@ boolean B_ParseAnglePosition(const char* desc, float* pos); boolean B_ParseStateCondition(statecondition_t* cond, const char* desc); boolean B_CheckAxisPos(ebstate_t test, float testPos, float pos); boolean B_CheckCondition(statecondition_t* cond, int localNum, struct bcontext_s* context); +boolean B_EqualConditions(const statecondition_t* a, const statecondition_t* b); void B_AppendDeviceDescToString(uint device, ddeventtype_t type, int id, ddstring_t* str); void B_AppendToggleStateToString(ebstate_t state, ddstring_t* str); void B_AppendAxisPositionToString(ebstate_t state, float pos, ddstring_t* str); diff --git a/doomsday/engine/portable/src/b_context.c b/doomsday/engine/portable/src/b_context.c index d9b93b6b68..72493b5bf6 100644 --- a/doomsday/engine/portable/src/b_context.c +++ b/doomsday/engine/portable/src/b_context.c @@ -712,6 +712,34 @@ int B_BindingsForControl(int localPlayer, const char* controlName, return numFound; } +boolean B_AreConditionsEqual(int count1, const statecondition_t* conds1, + int count2, const statecondition_t* conds2) +{ + int i, k; + + // Quick test (assumes there are no duplicated conditions). + if(count1 != count2) return false; + + for(i = 0; i < count1; ++i) + { + boolean found = false; + for(k = 0; k < count2; ++k) + { + if(B_EqualConditions(conds1 + i, conds2 + k)) + { + found = true; + break; + } + } + if(!found) return false; + } + return true; +} + +/** + * Looks through context @a bc and looks for a binding that matches either + * @a match1 or @a match2. + */ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1, dbinding_t* match2, evbinding_t** evResult, dbinding_t** dResult) @@ -726,15 +754,11 @@ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1, for(e = bc->commandBinds.next; e != &bc->commandBinds; e = e->next) { - // TODO: A bit lazy here, should also match all the conditions. - // Now we just consider all bindings with conditions unique... - if(e->numConds) - continue; - if(match1 && match1->bid != e->bid) { - if(match1->device == e->device && match1->id == e->id && - match1->type == e->type && match1->state == e->state) + if(B_AreConditionsEqual(match1->numConds, match1->conds, e->numConds, e->conds) && + match1->device == e->device && match1->id == e->id && + match1->type == e->type && match1->state == e->state) { *evResult = e; return true; @@ -742,8 +766,9 @@ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1, } if(match2) { - if(match2->device == e->device && match2->id == e->id && - match2->type == e->type) + if(B_AreConditionsEqual(match2->numConds, match2->conds, e->numConds, e->conds) && + match2->device == e->device && match2->id == e->id && + match2->type == e->type) { *evResult = e; return true; @@ -757,15 +782,11 @@ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1, { for(d = c->deviceBinds[i].next; d != &c->deviceBinds[i]; d = d->next) { - // Should also match all the conditions, now we just - // consider all bindings with conditions unique... - if(d->numConds) - continue; - if(match1) { - if(match1->device == d->device && match1->id == d->id && - match1->type == d->type) + if(B_AreConditionsEqual(match1->numConds, match1->conds, d->numConds, d->conds) && + match1->device == d->device && match1->id == d->id && + match1->type == d->type) { *dResult = d; return true; @@ -774,8 +795,9 @@ boolean B_FindMatchingBinding(bcontext_t* bc, evbinding_t* match1, if(match2 && match2->bid != d->bid) { - if(match2->device == d->device && match2->id == d->id && - match2->type == d->type) + if(B_AreConditionsEqual(match2->numConds, match2->conds, d->numConds, d->conds) && + match2->device == d->device && match2->id == d->id && + match2->type == d->type) { *dResult = d; return true; diff --git a/doomsday/engine/portable/src/b_main.c b/doomsday/engine/portable/src/b_main.c index f319623056..433bc156bc 100644 --- a/doomsday/engine/portable/src/b_main.c +++ b/doomsday/engine/portable/src/b_main.c @@ -314,7 +314,7 @@ void B_DeleteMatching(bcontext_t* bc, evbinding_t* eventBinding, while(B_FindMatchingBinding(bc, eventBinding, deviceBinding, &evb, &devb)) { // Only either evb or devb is returned as non-NULL. - int bid = (evb? evb->bid : (devb? devb->bid : 0)); + int bid = (evb? evb->bid : (devb? devb->bid : 0)); if(bid) { diff --git a/doomsday/engine/portable/src/b_util.c b/doomsday/engine/portable/src/b_util.c index 89e8e719eb..ed9b365a48 100644 --- a/doomsday/engine/portable/src/b_util.c +++ b/doomsday/engine/portable/src/b_util.c @@ -495,6 +495,17 @@ boolean B_CheckCondition(statecondition_t* cond, int localNum, bcontext_t* conte return !fulfilled; } +boolean B_EqualConditions(const statecondition_t* a, const statecondition_t* b) +{ + return (a->device == b->device && + a->type == b->type && + a->id == b->id && + a->state == b->state && + FEQUAL(a->pos, b->pos) && + a->flags.negate == b->flags.negate && + a->flags.multiplayer == b->flags.multiplayer); +} + void B_AppendDeviceDescToString(uint device, ddeventtype_t type, int id, ddstring_t* str) { inputdev_t* dev = I_GetDevice(device, false);