Move logic into messages rather than directly in the callback functions.
[enjoyable.git] / TargetMouseMove.m
index dd726e5..8bbfd42 100644 (file)
@@ -8,39 +8,80 @@
 
 #import "TargetMouseMove.h"
 
-@implementation TargetMouseMove
+#import "JoystickController.h"
 
--(void) setInputValue: (int) newIV {
-    NSPoint mouseLoc = [NSEvent mouseLocation];
-    if (dir == 0)
-        mouseLoc.x += newIV;
-    else
-        mouseLoc.y += newIV;
-    
-    CGEventRef move = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, CGPointMake(mouseLoc.x, mouseLoc.y), kCGMouseButtonLeft);
-    CGEventPost(kCGHIDEventTap, move);
-    CFRelease(move);
+@implementation TargetMouseMove {
+    int sign;
 }
 
-@synthesize dir;
+-(BOOL) isContinuous {
+    return YES;
+}
 
--(NSString*) stringify {
-       return [[NSString alloc] initWithFormat: @"mmove~%d", dir];
++ (NSString *)serializationCode {
+    return @"mmove";
 }
 
-+(TargetMouseMove*) unstringifyImpl: (NSArray*) comps {
-       NSParameterAssert([comps count] == 2);
-       TargetMouseMove* target = [[TargetMouseMove alloc] init];
-       [target setDir: [[comps objectAtIndex:1] integerValue]];
-       return target;
+- (NSDictionary *)serialize {
+    return @{ @"type": @"mmove", @"axis": @(_axis) };
 }
 
--(void) trigger {
-    return;
++ (Target *)targetDeserialize:(NSDictionary *)serialization
+                  withConfigs:(NSArray *)configs {
+       TargetMouseMove *target = [[TargetMouseMove alloc] init];
+    target.axis = [serialization[@"axis"] intValue];
+       return target;
 }
 
--(void) untrigger {
-    return;
+- (BOOL)update:(JoystickController *)jc {
+    if (fabsf(self.magnitude) < 0.01) {
+        sign = 0;
+        return NO; // dead zone
+    }
+
+    // If the action crossed over High/Low, this target is done.
+    if (!sign)
+        sign = self.magnitude < 0 ? -1 : 1;
+    else if (sign / self.magnitude < 0) {
+        sign = 0;
+        return NO;
+    }
+    
+    NSRect screenRect = [[NSScreen mainScreen] frame];
+    NSInteger height = screenRect.size.height;
+    
+    // TODO
+    float speed = 4.f;
+    if ([jc frontWindowOnly])
+        speed = 12.f;
+    float dx = 0.f, dy = 0.f;
+    if (_axis == 0)
+        dx = self.magnitude * speed;
+    else
+        dy = self.magnitude * speed;
+    NSPoint mouseLoc = jc.mouseLoc;
+    mouseLoc.x += dx;
+    mouseLoc.y -= dy;
+    jc.mouseLoc = mouseLoc;
+    
+    CGEventRef move = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved,
+                                              CGPointMake(mouseLoc.x, height - mouseLoc.y),
+                                              0);
+    CGEventSetType(move, kCGEventMouseMoved);
+    CGEventSetIntegerValueField(move, kCGMouseEventDeltaX, dx);
+    CGEventSetIntegerValueField(move, kCGMouseEventDeltaY, dy);
+    
+    if ([jc frontWindowOnly]) {
+        ProcessSerialNumber psn;
+        GetFrontProcess(&psn);
+        CGEventPostToPSN(&psn, move);
+    }
+    else {
+        CGEventPost(kCGHIDEventTap, move);
+    }
+    
+    CFRelease(move);
+    return YES;
 }
 
 @end