diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 378cc2f04..ddd635219 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,5 +1,6 @@ Changes towards version 0.7: -- Remove the unnecessary VControl memory abstraction layer - Michael +- Any input will register for at least one frame (Bug #864) - Michael +- Many VControl cleanups - Michael - Fix compilation without Netplay support - SvdB - Added limited AIFF sound file decoder for playing 3DO originals; SDX2 decoder by SvdB - Alex diff --git a/sc2/src/sc2code/gameinp.c b/sc2/src/sc2code/gameinp.c index 74d66e4f3..0458cc20b 100644 --- a/sc2/src/sc2code/gameinp.c +++ b/sc2/src/sc2code/gameinp.c @@ -233,6 +233,7 @@ UpdateInputState (void) CurrentInputState = ImmediateInputState; OldInputState = CachedInputState; CachedInputState = ImmediateInputState; + BeginInputFrame (); NewTime = GetTimeCounter (); if (_gestalt_keys) { diff --git a/sc2/src/sc2code/libs/inplib.h b/sc2/src/sc2code/libs/inplib.h index d898d71b7..bcb4b8bc9 100644 --- a/sc2/src/sc2code/libs/inplib.h +++ b/sc2/src/sc2code/libs/inplib.h @@ -55,5 +55,9 @@ void RebindInputState (int template, int control, int index); void SaveKeyConfiguration (uio_DirHandle *path, const char *fname); +/* Separate inputs into frames for dealing with very fast inputs */ + +void BeginInputFrame (void); + #endif /* _INPLIB_H */ diff --git a/sc2/src/sc2code/libs/input/sdl/input.c b/sc2/src/sc2code/libs/input/sdl/input.c index 59c4f882b..3628ae545 100644 --- a/sc2/src/sc2code/libs/input/sdl/input.c +++ b/sc2/src/sc2code/libs/input/sdl/input.c @@ -478,4 +478,10 @@ SaveKeyConfiguration (uio_DirHandle *path, const char *fname) } } +void +BeginInputFrame (void) +{ + VControl_BeginFrame (); +} + #endif diff --git a/sc2/src/sc2code/libs/input/sdl/vcontrol.c b/sc2/src/sc2code/libs/input/sdl/vcontrol.c index 09792a914..f61d5b4ad 100644 --- a/sc2/src/sc2code/libs/input/sdl/vcontrol.c +++ b/sc2/src/sc2code/libs/input/sdl/vcontrol.c @@ -385,7 +385,7 @@ activate (keybinding *i) { while (i != NULL) { - *(i->target) = *(i->target)+1; + *(i->target) = (*(i->target)+1) | VCONTROL_STARTBIT; i = i->next; } } @@ -395,9 +395,10 @@ deactivate (keybinding *i) { while (i != NULL) { - if (*(i->target) > 0) + int v = *(i->target) & VCONTROL_MASK; + if (v > 0) { - *(i->target) = *(i->target)-1; + *(i->target) = (v-1) | (*(i->target) & VCONTROL_STARTBIT); } i = i->next; } @@ -739,7 +740,7 @@ VControl_RemoveJoyHatBinding (int port, int which, Uint8 dir, int *target) } void -VControl_RemoveAllBindings () +VControl_RemoveAllBindings (void) { key_uninit (); key_init (); @@ -861,7 +862,7 @@ VControl_ProcessJoyHat (int port, int which, Uint8 value) } void -VControl_ResetInput () +VControl_ResetInput (void) { /* Step through every valid entry in the binding pool and zero * them out. This will probably zero entries multiple times; @@ -882,6 +883,28 @@ VControl_ResetInput () } } +void +VControl_BeginFrame (void) +{ + /* Step through every valid entry in the binding pool and zero + * out the frame-start bit. This will probably zero entries + * multiple times; oh well, no harm done. */ + + keypool *base = pool; + while (base != NULL) + { + int i; + for (i = 0; i < POOL_CHUNK_SIZE; i++) + { + if(base->pool[i].target) + { + *(base->pool[i].target) &= VCONTROL_MASK; + } + } + base = base->next; + } +} + void VControl_HandleEvent (const SDL_Event *e) { diff --git a/sc2/src/sc2code/libs/input/sdl/vcontrol.h b/sc2/src/sc2code/libs/input/sdl/vcontrol.h index 1e65f92b4..1c6f81981 100644 --- a/sc2/src/sc2code/libs/input/sdl/vcontrol.h +++ b/sc2/src/sc2code/libs/input/sdl/vcontrol.h @@ -63,6 +63,9 @@ void VControl_RemoveJoyHatBinding (int port, int which, Uint8 dir, int *target); void VControl_RemoveAllBindings (void); +/* Signal to VControl that a frame is about to begin. */ +void VControl_BeginFrame (void); + /* The listener. Routines besides HandleEvent may be used to 'fake' inputs without * fabricating an SDL_Event. */ @@ -119,4 +122,14 @@ int VControl_NextBinding (VCONTROL_GESTURE *gesture); void VControl_ClearGesture (void); int VControl_GetLastGesture (VCONTROL_GESTURE *g); +/* Constants for handling the "Start bit." If a gesture is made, and + * then ends, within a single frame, it will still, for one frame, + * have a nonzero value. This is because Bit 16 will be on for the + * first frame a gesture is struck. This bit is cleared when + * VControl_BeginFrame() is called. These constants are used to mask + * out results if necessary. */ + +#define VCONTROL_STARTBIT 0x10000 +#define VCONTROL_MASK 0x0FFFF + #endif