xp12camera

Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/xp12camera.git

test

Commit ca1018314222d3e2679463750d3d987c5622951c by SM <seb.michalk@gmail.com> on 2025-06-26 08:43:49 +0200
diff --git a/FLIR_Camera.cpp b/FLIR_Camera.cpp
index 9fb294d..bec1dd0 100644
--- a/FLIR_Camera.cpp
+++ b/FLIR_Camera.cpp
@@ -25,7 +25,8 @@
  #include "XPLMGraphics.h"
  #include "XPLMProcessing.h"
  #include "XPLMMenus.h"
- #include "FLIR_LockOn.h"
+ #include "FLIR_SimpleLock.h"
+ #include "FLIR_VisualEffects.h"
 
  // OpenGL includes for MinGW
  #include <windows.h>
@@ -109,8 +110,11 @@ static void DrawRealisticThermalOverlay(void);
      // Dataref for HUD control
      gManipulatorDisabled = XPLMFindDataRef("sim/operation/prefs/misc/manipulator_disabled");
 
-     // Initialize lock-on system
-     InitializeLockOnSystem();
+     // Initialize simple lock system
+     InitializeSimpleLock();
+     
+     // Initialize visual effects system
+     InitializeVisualEffects();
 
      // Register hotkeys
      gActivateKey = XPLMRegisterHotKey(XPLM_VK_F9, xplm_DownFlag,
@@ -142,7 +146,7 @@ static void DrawRealisticThermalOverlay(void);
                                        TiltDownCallback, NULL);
 
      gThermalToggleKey = XPLMRegisterHotKey(XPLM_VK_T, xplm_DownFlag,
-                                           "FLIR Thermal Toggle",
+                                           "FLIR Visual Effects Toggle",
                                            ThermalToggleCallback, NULL);
     
     gFocusLockKey = XPLMRegisterHotKey(XPLM_VK_SPACE, xplm_DownFlag,
@@ -216,8 +220,8 @@ static void DrawRealisticThermalOverlay(void);
              XPLMSetDatai(gManipulatorDisabled, 0);
          }
          
-         // Disable lock-on when camera deactivated
-         DisableLockOn();
+         // Disable lock when camera deactivated
+         DisableSimpleLock();
          
          // Unregister drawing callback to save performance
         if (gDrawCallbackRegistered) {
@@ -277,7 +281,7 @@ static void DrawRealisticThermalOverlay(void);
  
  static void PanLeftCallback(void* inRefcon)
  {
-     if (gCameraActive && !IsLockOnActive()) { // Only when not locked
+     if (gCameraActive && !IsSimpleLockActive()) { // Only when not locked
          gCameraPan -= 0.5f; // Very sensitive control
          if (gCameraPan < -180.0f) gCameraPan += 360.0f;
          char msg[256];
@@ -288,7 +292,7 @@ static void DrawRealisticThermalOverlay(void);
  
  static void PanRightCallback(void* inRefcon)
  {
-     if (gCameraActive && !IsLockOnActive()) { // Only when not locked
+     if (gCameraActive && !IsSimpleLockActive()) { // Only when not locked
          gCameraPan += 0.5f; // Very sensitive control
          if (gCameraPan > 180.0f) gCameraPan -= 360.0f;
          char msg[256];
@@ -299,7 +303,7 @@ static void DrawRealisticThermalOverlay(void);
  
  static void TiltUpCallback(void* inRefcon)
  {
-     if (gCameraActive && !IsLockOnActive()) { // Only when not locked
+     if (gCameraActive && !IsSimpleLockActive()) { // Only when not locked
          gCameraTilt = fminf(gCameraTilt + 0.5f, 45.0f); // Very sensitive control
          char msg[256];
          sprintf(msg, "FLIR Camera System: Tilt %.1f degrees\n", gCameraTilt);
@@ -309,7 +313,7 @@ static void DrawRealisticThermalOverlay(void);
  
  static void TiltDownCallback(void* inRefcon)
  {
-     if (gCameraActive && !IsLockOnActive()) { // Only when not locked
+     if (gCameraActive && !IsSimpleLockActive()) { // Only when not locked
          gCameraTilt = fmaxf(gCameraTilt - 0.5f, -90.0f); // Very sensitive control
          char msg[256];
          sprintf(msg, "FLIR Camera System: Tilt %.1f degrees\n", gCameraTilt);
@@ -320,25 +324,22 @@ static void DrawRealisticThermalOverlay(void);
  static void ThermalToggleCallback(void* inRefcon)
  {
      if (gCameraActive) {
-         gThermalMode = (gThermalMode + 1) % 3;
-         char msg[256];
-         const char* modeNames[] = {"Off", "White Hot", "Enhanced"};
-         sprintf(msg, "FLIR Camera System: Thermal mode %s\n", modeNames[gThermalMode]);
-         XPLMDebugString(msg);
+         // Cycle through visual effect modes
+         CycleVisualModes();
      }
  }
 
 static void FocusLockCallback(void* inRefcon)
 {
     if (gCameraActive) {
-        if (!IsLockOnActive()) {
-            // Lock on to current camera direction at 1000m distance
-            SetArbitraryLockPoint(gCameraPan, gCameraTilt, 1000.0f);
-            XPLMDebugString("FLIR Camera System: Lock-on activated\n");
+        if (!IsSimpleLockActive()) {
+            // Lock to current camera direction
+            LockCurrentDirection(gCameraPan, gCameraTilt);
+            XPLMDebugString("FLIR Camera System: Direction locked\n");
         } else {
-            // Disable lock-on
-            DisableLockOn();
-            XPLMDebugString("FLIR Camera System: Lock-on disabled\n");
+            // Disable lock
+            DisableSimpleLock();
+            XPLMDebugString("FLIR Camera System: Lock disabled\n");
         }
     }
 }
@@ -359,7 +360,7 @@ static void FocusLockCallback(void* inRefcon)
          if (gManipulatorDisabled) {
              XPLMSetDatai(gManipulatorDisabled, 0);
          }
-         DisableLockOn();
+         DisableSimpleLock();
          return 0;
      }
      
@@ -376,7 +377,7 @@ static void FocusLockCallback(void* inRefcon)
      float planeRoll = XPLMGetDataf(gPlaneRoll);
      
      // Mouse control for camera movement (only when not locked)
-     if (!IsLockOnActive()) {
+     if (!IsSimpleLockActive()) {
          int mouseX, mouseY;
          XPLMGetMouseLocation(&mouseX, &mouseY);
          
@@ -399,14 +400,12 @@ static void FocusLockCallback(void* inRefcon)
          gLastMouseX = mouseX;
          gLastMouseY = mouseY;
      } else {
-         // Update camera angles based on lock-on point
-         UpdateCameraToLockPoint(&gCameraPan, &gCameraTilt);
+         // Use locked camera angles
+         GetLockedAngles(&gCameraPan, &gCameraTilt);
      }
      
      // Calculate camera position (belly-mounted)
      float headingRad = planeHeading * M_PI / 180.0f;
-     float pitchRad = planePitch * M_PI / 180.0f;
-     float rollRad = planeRoll * M_PI / 180.0f;
      
      // Position camera below and slightly forward of aircraft center
      outCameraPosition->x = planeX + gCameraDistance * sin(headingRad);
@@ -436,13 +435,16 @@ static void FocusLockCallback(void* inRefcon)
      return 1;
  }
 
-// Realistic thermal overlay drawing
+// Enhanced thermal overlay with visual effects
 static void DrawRealisticThermalOverlay(void)
 {
     int screenWidth, screenHeight;
     XPLMGetScreenSize(&screenWidth, &screenHeight);
     
-    // Set up OpenGL for 2D drawing
+    // Apply visual effects (monochrome, thermal, noise, etc.)
+    RenderVisualEffects(screenWidth, screenHeight);
+    
+    // Set up OpenGL for crosshair drawing
     glMatrixMode(GL_PROJECTION);
     glPushMatrix();
     glLoadIdentity();
@@ -457,33 +459,12 @@ static void DrawRealisticThermalOverlay(void)
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     
-    // Noise filter effect for thermal camera realism
-    if (gThermalMode > 0) {
-        glColor4f(0.8f, 0.8f, 0.8f, 0.1f);
-        glBegin(GL_POINTS);
-        for (int i = 0; i < 500; i++) {
-            float x = (rand() % screenWidth);
-            float y = (rand() % screenHeight);
-            glVertex2f(x, y);
-        }
-        glEnd();
-        
-        // Subtle scan lines
-        glColor4f(0.7f, 0.7f, 0.7f, 0.05f);
-        glBegin(GL_LINES);
-        for (int y = 0; y < screenHeight; y += 4) {
-            glVertex2f(0, y);
-            glVertex2f(screenWidth, y);
-        }
-        glEnd();
-    }
-    
     // Draw crosshair in center
     float centerX = screenWidth / 2.0f;
     float centerY = screenHeight / 2.0f;
     
     // Set color based on lock status
-    if (IsLockOnActive()) {
+    if (IsSimpleLockActive()) {
         glColor4f(1.0f, 0.0f, 0.0f, 0.9f); // Red when locked
     } else {
         glColor4f(0.0f, 1.0f, 0.0f, 0.9f); // Bright green when scanning
diff --git a/FLIR_Camera.o b/FLIR_Camera.o
index 6c33f07..21036a3 100644
Binary files a/FLIR_Camera.o and b/FLIR_Camera.o differ
diff --git a/FLIR_SimpleLock.cpp b/FLIR_SimpleLock.cpp
new file mode 100644
index 0000000..6ff8edb
--- /dev/null
+++ b/FLIR_SimpleLock.cpp
@@ -0,0 +1,74 @@
+/*
+ * FLIR_SimpleLock.cpp
+ * 
+ * Simple arbitrary point lock-on system
+ * Just locks the current camera direction relative to aircraft heading
+ * Perfect for tracking moving ships, vehicles, or any visual target
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "XPLMDataAccess.h"
+#include "XPLMUtilities.h"
+#include "FLIR_SimpleLock.h"
+
+// Lock-on state
+static int gLockActive = 0;
+static float gLockedPan = 0.0f;     // Pan angle relative to aircraft when locked
+static float gLockedTilt = 0.0f;    // Tilt angle when locked
+
+void InitializeSimpleLock()
+{
+    gLockActive = 0;
+    XPLMDebugString("FLIR Simple Lock: Initialized\n");
+}
+
+void LockCurrentDirection(float currentPan, float currentTilt)
+{
+    // Simply store the current camera angles
+    gLockedPan = currentPan;
+    gLockedTilt = currentTilt;
+    gLockActive = 1;
+    
+    char msg[256];
+    sprintf(msg, "FLIR Simple Lock: Locked at Pan=%.1f°, Tilt=%.1f°\n", 
+            gLockedPan, gLockedTilt);
+    XPLMDebugString(msg);
+}
+
+void GetLockedAngles(float* outPan, float* outTilt)
+{
+    if (!gLockActive) {
+        return;
+    }
+    
+    // Simply return the locked angles - camera stays fixed relative to aircraft
+    *outPan = gLockedPan;
+    *outTilt = gLockedTilt;
+}
+
+void DisableSimpleLock()
+{
+    gLockActive = 0;
+    XPLMDebugString("FLIR Simple Lock: Disabled\n");
+}
+
+int IsSimpleLockActive()
+{
+    return gLockActive;
+}
+
+void GetSimpleLockStatus(char* statusBuffer, int bufferSize)
+{
+    if (!gLockActive) {
+        strncpy(statusBuffer, "LOCK: OFF", bufferSize - 1);
+        statusBuffer[bufferSize - 1] = '\0';
+        return;
+    }
+    
+    snprintf(statusBuffer, bufferSize, "LOCK: ON %.1f°/%.1f°", gLockedPan, gLockedTilt);
+    statusBuffer[bufferSize - 1] = '\0';
+}
\ No newline at end of file
diff --git a/FLIR_SimpleLock.h b/FLIR_SimpleLock.h
new file mode 100644
index 0000000..6a7216f
--- /dev/null
+++ b/FLIR_SimpleLock.h
@@ -0,0 +1,36 @@
+/*
+ * FLIR_SimpleLock.h
+ * 
+ * Header file for simple arbitrary point lock-on system
+ */
+
+#ifndef FLIR_SIMPLELOCK_H
+#define FLIR_SIMPLELOCK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Initialize the simple lock system
+void InitializeSimpleLock();
+
+// Lock to current camera direction
+void LockCurrentDirection(float currentPan, float currentTilt);
+
+// Get locked camera angles
+void GetLockedAngles(float* outPan, float* outTilt);
+
+// Disable lock
+void DisableSimpleLock();
+
+// Check if lock is active
+int IsSimpleLockActive();
+
+// Get lock status string for display
+void GetSimpleLockStatus(char* statusBuffer, int bufferSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FLIR_SIMPLELOCK_H
\ No newline at end of file
diff --git a/FLIR_SimpleLock.o b/FLIR_SimpleLock.o
new file mode 100644
index 0000000..349f49e
Binary files /dev/null and b/FLIR_SimpleLock.o differ
diff --git a/FLIR_VisualEffects.cpp b/FLIR_VisualEffects.cpp
new file mode 100644
index 0000000..2c050d0
--- /dev/null
+++ b/FLIR_VisualEffects.cpp
@@ -0,0 +1,290 @@
+/*
+ * FLIR_VisualEffects.cpp
+ * 
+ * Visual effects system for realistic military camera simulation
+ * Implements monochrome filters, thermal effects, and military camera aesthetics
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#include "XPLMDisplay.h"
+#include "XPLMGraphics.h"
+#include "XPLMDataAccess.h"
+#include "XPLMUtilities.h"
+#include "FLIR_VisualEffects.h"
+
+// OpenGL includes for MinGW
+#include <windows.h>
+#include <GL/gl.h>
+
+// Visual effects state
+static int gMonochromeEnabled = 0;
+static int gThermalEnabled = 1;
+static int gNoiseEnabled = 1;
+static int gScanLinesEnabled = 1;
+static float gBrightness = 1.0f;
+static float gContrast = 1.2f;
+
+// Effect parameters
+static float gNoiseIntensity = 0.1f;
+static float gScanLineOpacity = 0.05f;
+static int gFrameCounter = 0;
+
+void InitializeVisualEffects()
+{
+    srand(time(NULL));
+    XPLMDebugString("FLIR Visual Effects: Initialized\n");
+}
+
+void SetMonochromeFilter(int enabled)
+{
+    gMonochromeEnabled = enabled;
+    char msg[256];
+    sprintf(msg, "FLIR Visual Effects: Monochrome %s\n", enabled ? "ON" : "OFF");
+    XPLMDebugString(msg);
+}
+
+void SetThermalMode(int enabled)
+{
+    gThermalEnabled = enabled;
+    char msg[256];
+    sprintf(msg, "FLIR Visual Effects: Thermal %s\n", enabled ? "ON" : "OFF");
+    XPLMDebugString(msg);
+}
+
+void SetImageEnhancement(float brightness, float contrast)
+{
+    gBrightness = brightness;
+    gContrast = contrast;
+    char msg[256];
+    sprintf(msg, "FLIR Visual Effects: Brightness=%.1f, Contrast=%.1f\n", brightness, contrast);
+    XPLMDebugString(msg);
+}
+
+void RenderVisualEffects(int screenWidth, int screenHeight)
+{
+    gFrameCounter++;
+    
+    // Set up OpenGL for 2D screen-space effects
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    glOrtho(0, screenWidth, screenHeight, 0, -1, 1);
+    
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+    
+    // Disable depth testing for screen overlays
+    glDisable(GL_DEPTH_TEST);
+    glEnable(GL_BLEND);
+    
+    // Apply monochrome filter
+    if (gMonochromeEnabled) {
+        RenderMonochromeFilter(screenWidth, screenHeight);
+    }
+    
+    // Apply thermal vision effects
+    if (gThermalEnabled) {
+        RenderThermalEffects(screenWidth, screenHeight);
+    }
+    
+    // Add camera noise/grain
+    if (gNoiseEnabled) {
+        RenderCameraNoise(screenWidth, screenHeight);
+    }
+    
+    // Add scan lines for CRT-like effect
+    if (gScanLinesEnabled) {
+        RenderScanLines(screenWidth, screenHeight);
+    }
+    
+    // Restore OpenGL state
+    glEnable(GL_DEPTH_TEST);
+    glDisable(GL_BLEND);
+    glPopMatrix();
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+}
+
+void RenderMonochromeFilter(int screenWidth, int screenHeight)
+{
+    // Monochrome overlay using color blending
+    glBlendFunc(GL_DST_COLOR, GL_ZERO); // Multiply blend mode
+    
+    // Create a subtle green monochrome tint (military night vision style)
+    glColor4f(0.3f, 1.0f, 0.3f, 1.0f);
+    
+    glBegin(GL_QUADS);
+    glVertex2f(0, 0);
+    glVertex2f(screenWidth, 0);
+    glVertex2f(screenWidth, screenHeight);
+    glVertex2f(0, screenHeight);
+    glEnd();
+    
+    // Add brightness/contrast adjustment
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    
+    float brightness_adj = (gBrightness - 1.0f) * 0.3f;
+    if (brightness_adj > 0) {
+        glColor4f(brightness_adj, brightness_adj, brightness_adj, 0.5f);
+    } else {
+        glColor4f(0.0f, 0.0f, 0.0f, -brightness_adj * 0.5f);
+    }
+    
+    glBegin(GL_QUADS);
+    glVertex2f(0, 0);
+    glVertex2f(screenWidth, 0);
+    glVertex2f(screenWidth, screenHeight);
+    glVertex2f(0, screenHeight);
+    glEnd();
+}
+
+void RenderThermalEffects(int screenWidth, int screenHeight)
+{
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    
+    // Thermal overlay with heat signature simulation
+    glColor4f(1.0f, 0.4f, 0.0f, 0.15f); // Orange thermal tint
+    
+    glBegin(GL_QUADS);
+    glVertex2f(0, 0);
+    glVertex2f(screenWidth, 0);
+    glVertex2f(screenWidth, screenHeight);
+    glVertex2f(0, screenHeight);
+    glEnd();
+    
+    // Add thermal border indicators
+    glColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+    glLineWidth(1.0f);
+    
+    glBegin(GL_LINES);
+    // Temperature scale on left
+    for (int i = 0; i < 10; i++) {
+        float y = 50 + i * (screenHeight - 100) / 10.0f;
+        glVertex2f(10, y);
+        glVertex2f(25, y);
+    }
+    glEnd();
+    
+    // Add "WHT HOT" indicator
+    // (Text would be drawn here if we had font rendering)
+}
+
+void RenderCameraNoise(int screenWidth, int screenHeight)
+{
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    
+    // Random noise points for camera grain effect
+    glColor4f(1.0f, 1.0f, 1.0f, gNoiseIntensity);
+    glPointSize(1.0f);
+    
+    glBegin(GL_POINTS);
+    
+    // Generate pseudo-random noise based on frame counter
+    srand(gFrameCounter / 2); // Change noise every 2 frames
+    
+    int noisePoints = (screenWidth * screenHeight) / 2000; // Density control
+    for (int i = 0; i < noisePoints; i++) {
+        float x = rand() % screenWidth;
+        float y = rand() % screenHeight;
+        
+        // Vary intensity per pixel
+        float intensity = (rand() % 100) / 100.0f * gNoiseIntensity;
+        glColor4f(intensity, intensity, intensity, intensity);
+        glVertex2f(x, y);
+    }
+    
+    glEnd();
+    
+    // Add electronic interference lines occasionally
+    if ((gFrameCounter % 120) < 3) { // Brief interference every 2 seconds
+        glColor4f(1.0f, 1.0f, 1.0f, 0.3f);
+        glLineWidth(1.0f);
+        
+        glBegin(GL_LINES);
+        for (int i = 0; i < 5; i++) {
+            float y = rand() % screenHeight;
+            glVertex2f(0, y);
+            glVertex2f(screenWidth, y);
+        }
+        glEnd();
+    }
+}
+
+void RenderScanLines(int screenWidth, int screenHeight)
+{
+    if (gScanLineOpacity <= 0.0f) return;
+    
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glColor4f(0.0f, 0.0f, 0.0f, gScanLineOpacity);
+    glLineWidth(1.0f);
+    
+    // Horizontal scan lines every 2-3 pixels
+    glBegin(GL_LINES);
+    for (int y = 2; y < screenHeight; y += 3) {
+        glVertex2f(0, y);
+        glVertex2f(screenWidth, y);
+    }
+    glEnd();
+}
+
+void CycleVisualModes()
+{
+    static int mode = 0;
+    mode = (mode + 1) % 4;
+    
+    switch (mode) {
+        case 0: // Standard
+            SetMonochromeFilter(0);
+            SetThermalMode(0);
+            gNoiseEnabled = 0;
+            gScanLinesEnabled = 0;
+            XPLMDebugString("FLIR Visual Effects: Standard Mode\n");
+            break;
+            
+        case 1: // Monochrome
+            SetMonochromeFilter(1);
+            SetThermalMode(0);
+            gNoiseEnabled = 1;
+            gScanLinesEnabled = 1;
+            XPLMDebugString("FLIR Visual Effects: Monochrome Mode\n");
+            break;
+            
+        case 2: // Thermal
+            SetMonochromeFilter(0);
+            SetThermalMode(1);
+            gNoiseEnabled = 1;
+            gScanLinesEnabled = 0;
+            XPLMDebugString("FLIR Visual Effects: Thermal Mode\n");
+            break;
+            
+        case 3: // Enhanced
+            SetMonochromeFilter(1);
+            SetThermalMode(1);
+            gNoiseEnabled = 1;
+            gScanLinesEnabled = 1;
+            XPLMDebugString("FLIR Visual Effects: Enhanced Mode\n");
+            break;
+    }
+}
+
+void GetVisualEffectsStatus(char* statusBuffer, int bufferSize)
+{
+    const char* mode = "STANDARD";
+    if (gMonochromeEnabled && gThermalEnabled) mode = "ENHANCED";
+    else if (gThermalEnabled) mode = "THERMAL";
+    else if (gMonochromeEnabled) mode = "MONO";
+    
+    snprintf(statusBuffer, bufferSize, "VFX: %s", mode);
+    statusBuffer[bufferSize - 1] = '\0';
+}
\ No newline at end of file
diff --git a/FLIR_VisualEffects.h b/FLIR_VisualEffects.h
new file mode 100644
index 0000000..8994e8b
--- /dev/null
+++ b/FLIR_VisualEffects.h
@@ -0,0 +1,41 @@
+/*
+ * FLIR_VisualEffects.h
+ * 
+ * Header file for military camera visual effects system
+ */
+
+#ifndef FLIR_VISUALEFFECTS_H
+#define FLIR_VISUALEFFECTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Initialize the visual effects system
+void InitializeVisualEffects();
+
+// Main rendering function - call from drawing callback
+void RenderVisualEffects(int screenWidth, int screenHeight);
+
+// Individual effect controls
+void SetMonochromeFilter(int enabled);
+void SetThermalMode(int enabled);
+void SetImageEnhancement(float brightness, float contrast);
+
+// Individual effect renderers
+void RenderMonochromeFilter(int screenWidth, int screenHeight);
+void RenderThermalEffects(int screenWidth, int screenHeight);
+void RenderCameraNoise(int screenWidth, int screenHeight);
+void RenderScanLines(int screenWidth, int screenHeight);
+
+// Quick mode switching
+void CycleVisualModes();
+
+// Status display
+void GetVisualEffectsStatus(char* statusBuffer, int bufferSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FLIR_VISUALEFFECTS_H
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 77a32a4..ca9626f 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@ LDFLAGS += $(LIBS)
 LDFLAGS += -lopengl32 -lgdi32
 
 # Source files
-SOURCES = FLIR_Camera.cpp FLIR_LockOn.cpp
+SOURCES = FLIR_Camera.cpp FLIR_SimpleLock.cpp FLIR_VisualEffects.cpp
 
 # Object files
 OBJECTS = $(SOURCES:.cpp=.o)
diff --git a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl
index bf2cd71..3d03f66 100755
Binary files a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl and b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl differ