2
0
Эх сурвалжийг харах

Goo Cursor update to SDK projects and MG 3.8.*

CartBlanche 1 долоо хоног өмнө
parent
commit
31d5b3db4e
30 өөрчлөгдсөн 1016 нэмэгдсэн , 783 устгасан
  1. 37 0
      GooCursor/.vscode/launch.json
  2. 144 0
      GooCursor/.vscode/tasks.json
  3. 0 0
      GooCursor/Core/Content/Game.ico
  4. 0 0
      GooCursor/Core/Content/GameThumbnail.png
  5. 60 60
      GooCursor/Core/Content/SimpleFont.spritefont
  6. 0 0
      GooCursor/Core/Content/SimpleFont.xnb
  7. 0 0
      GooCursor/Core/Content/cursor.bmp
  8. 0 0
      GooCursor/Core/Content/cursor.xnb
  9. 264 274
      GooCursor/Core/Cursor.cs
  10. 159 163
      GooCursor/Core/Game1.cs
  11. 8 0
      GooCursor/Core/GooCursor.Core.csproj
  12. 0 71
      GooCursor/GooCursor.Linux.csproj
  13. 0 85
      GooCursor/GooCursor.MacOS.csproj
  14. 52 29
      GooCursor/GooCursor.sln
  15. 27 0
      GooCursor/Platforms/Android/AndroidManifest.xml
  16. 22 0
      GooCursor/Platforms/Android/GooCursor.Android.csproj
  17. 34 0
      GooCursor/Platforms/Android/MainActivity.cs
  18. 23 0
      GooCursor/Platforms/Desktop/GooCursor.DesktopGL.csproj
  19. 14 0
      GooCursor/Platforms/Desktop/Program.cs
  20. 0 0
      GooCursor/Platforms/Linux/GooCursor.Linux.csproj
  21. 0 0
      GooCursor/Platforms/MacOS/GooCursor.MacOS.csproj
  22. 25 0
      GooCursor/Platforms/Windows/GooCursor.Windows.csproj
  23. 14 0
      GooCursor/Platforms/Windows/Program.cs
  24. 43 0
      GooCursor/Platforms/Windows/app.manifest
  25. 22 0
      GooCursor/Platforms/iOS/GooCursor.iOS.csproj
  26. 0 0
      GooCursor/Platforms/iOS/Info.plist
  27. 12 0
      GooCursor/Platforms/iOS/Program.cs
  28. 0 65
      GooCursor/Program.cs
  29. 0 33
      GooCursor/Properties/AssemblyInfo.cs
  30. 56 3
      GooCursor/Readme.md

+ 37 - 0
GooCursor/.vscode/launch.json

@@ -0,0 +1,37 @@
+{
+    "version": "2.0.0",
+    "configurations": [
+        {
+            "name": "Launch Windows",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-windows",
+            "program": "${workspaceFolder}/Platforms/Windows/bin/Debug/net8.0-windows/GooCursor.Windows.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Windows",
+            "console": "internalConsole",
+            "stopAtEntry": false
+        },
+        {
+            "name": "Launch DesktopGL",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl",
+            "program": "${workspaceFolder}/Platforms/Desktop/bin/Debug/net8.0/GooCursor.DesktopGL.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Desktop",
+            "console": "internalConsole",
+            "stopAtEntry": false
+        },
+        {
+            "name": "Attach to Windows",
+            "type": "coreclr",
+            "request": "attach"
+        },
+        {
+            "name": "Attach to DesktopGL",
+            "type": "coreclr",
+            "request": "attach"
+        }
+    ]
+}

+ 144 - 0
GooCursor/.vscode/tasks.json

@@ -0,0 +1,144 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build-windows",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "build",
+                "Platforms/Windows/GooCursor.Windows.csproj",
+                "--configuration",
+                "Debug"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "silent",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-desktopgl",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "build",
+                "Platforms/Desktop/GooCursor.DesktopGL.csproj",
+                "--configuration",
+                "Debug"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "silent",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-android",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "build",
+                "Platforms/Android/GooCursor.Android.csproj",
+                "--configuration",
+                "Debug"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "always",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            },
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "clean",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "clean"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "always",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            }
+        },
+        {
+            "label": "restore",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "restore"
+            ],
+            "group": "build",
+            "presentation": {
+                "echo": true,
+                "reveal": "always",
+                "focus": false,
+                "panel": "shared",
+                "showReuseMessage": true,
+                "clear": false
+            }
+        },
+        {
+            "label": "run-windows",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "run",
+                "--project",
+                "Platforms/Windows/GooCursor.Windows.csproj"
+            ],
+            "group": "test",
+            "dependsOn": "build-windows",
+            "presentation": {
+                "echo": true,
+                "reveal": "always",
+                "focus": true,
+                "panel": "shared",
+                "showReuseMessage": false,
+                "clear": true
+            },
+            "isBackground": false
+        },
+        {
+            "label": "run-desktopgl",
+            "command": "dotnet",
+            "type": "shell",
+            "args": [
+                "run",
+                "--project",
+                "Platforms/Desktop/GooCursor.DesktopGL.csproj"
+            ],
+            "group": "test",
+            "dependsOn": "build-desktopgl",
+            "presentation": {
+                "echo": true,
+                "reveal": "always",
+                "focus": true,
+                "panel": "shared",
+                "showReuseMessage": false,
+                "clear": true
+            },
+            "isBackground": false
+        }
+    ]
+}

+ 0 - 0
GooCursor/Game.ico → GooCursor/Core/Content/Game.ico


+ 0 - 0
GooCursor/GameThumbnail.png → GooCursor/Core/Content/GameThumbnail.png


+ 60 - 60
GooCursor/Content/SimpleFont.spritefont → GooCursor/Core/Content/SimpleFont.spritefont

@@ -1,60 +1,60 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-This file contains an xml description of a font, and will be read by the XNA
-Framework Content Pipeline. Follow the comments to customize the appearance
-of the font in your game, and to change the characters which are available to draw
-with.
--->
-<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
-  <Asset Type="Graphics:FontDescription">
-
-    <!--
-    Modify this string to change the font that will be imported.
-    -->
-    <FontName>Lucida Console</FontName>
-
-    <!--
-    Size is a float value, measured in points. Modify this value to change
-    the size of the font.
-    -->
-    <Size>14</Size>
-
-    <!--
-    Spacing is a float value, measured in pixels. Modify this value to change
-    the amount of spacing in between characters.
-    -->
-    <Spacing>0</Spacing>
-
-    <!--
-    UseKerning controls the layout of the font. If this value is true, kerning information
-    will be used when placing characters.
-    -->
-    <UseKerning>true</UseKerning>
-
-    <!--
-    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
-    and "Bold, Italic", and are case sensitive.
-    -->
-    <Style>Regular</Style>
-
-    <!--
-    If you uncomment this line, the default character will be substituted if you draw
-    or measure text that contains characters which were not included in the font.
-    -->
-    <!-- <DefaultCharacter>*</DefaultCharacter> -->
-
-    <!--
-    CharacterRegions control what letters are available in the font. Every
-    character from Start to End will be built and made available for drawing. The
-    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
-    character set. The characters are ordered according to the Unicode standard.
-    See the documentation for more information.
-    -->
-    <CharacterRegions>
-      <CharacterRegion>
-        <Start>&#32;</Start>
-        <End>&#126;</End>
-      </CharacterRegion>
-    </CharacterRegions>
-  </Asset>
-</XnaContent>
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This file contains an xml description of a font, and will be read by the XNA
+Framework Content Pipeline. Follow the comments to customize the appearance
+of the font in your game, and to change the characters which are available to draw
+with.
+-->
+<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
+  <Asset Type="Graphics:FontDescription">
+
+    <!--
+    Modify this string to change the font that will be imported.
+    -->
+    <FontName>Lucida Console</FontName>
+
+    <!--
+    Size is a float value, measured in points. Modify this value to change
+    the size of the font.
+    -->
+    <Size>14</Size>
+
+    <!--
+    Spacing is a float value, measured in pixels. Modify this value to change
+    the amount of spacing in between characters.
+    -->
+    <Spacing>0</Spacing>
+
+    <!--
+    UseKerning controls the layout of the font. If this value is true, kerning information
+    will be used when placing characters.
+    -->
+    <UseKerning>true</UseKerning>
+
+    <!--
+    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
+    and "Bold, Italic", and are case sensitive.
+    -->
+    <Style>Regular</Style>
+
+    <!--
+    If you uncomment this line, the default character will be substituted if you draw
+    or measure text that contains characters which were not included in the font.
+    -->
+    <!-- <DefaultCharacter>*</DefaultCharacter> -->
+
+    <!--
+    CharacterRegions control what letters are available in the font. Every
+    character from Start to End will be built and made available for drawing. The
+    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
+    character set. The characters are ordered according to the Unicode standard.
+    See the documentation for more information.
+    -->
+    <CharacterRegions>
+      <CharacterRegion>
+        <Start>&#32;</Start>
+        <End>&#126;</End>
+      </CharacterRegion>
+    </CharacterRegions>
+  </Asset>
+</XnaContent>

+ 0 - 0
GooCursor/Content/SimpleFont.xnb → GooCursor/Core/Content/SimpleFont.xnb


+ 0 - 0
GooCursor/Content/cursor.bmp → GooCursor/Core/Content/cursor.bmp


+ 0 - 0
GooCursor/Content/cursor.xnb → GooCursor/Core/Content/cursor.xnb


+ 264 - 274
GooCursor/Cursor.cs → GooCursor/Core/Cursor.cs

@@ -1,274 +1,264 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Input;
-
-namespace GooCursor
-{
-    public class Cursor : DrawableGameComponent
-    {
-        #region Private Structures
-        private struct TrailNode
-        {
-            public Vector2 Position;
-            public Vector2 Velocity;
-        }
-        #endregion
-
-        #region Fields and properties
-        // this is the sprite that is drawn at the current cursor position.
-        // textureCenter is used to center the sprite when drawing.
-        private Texture2D cursorTexture;
-        private Vector2 textureCenter;
-        private SpriteBatch spriteBatch;
-
-        private Vector2 position;
-        private int trailNodeCount;
-        private TrailNode[] trailNodes;
-
-
-        /// <summary>
-        /// Gets of Sets the screen position of the cursor
-        /// </summary>
-        public Vector2 Position
-        {
-            get { return position; }
-            set { position = value; }
-        }
-        /// <summary>
-        /// Gets of Sets the stiffness of the trail
-        /// A lower number means the trail will be longer
-        /// </summary>
-        public float TrailStiffness { get; set; }
-
-        /// <summary>
-        /// Controls the damping of the velocity of trail nodes
-        /// </summary>
-        public float TrailDamping { get; set; }
-
-        /// <summary>
-        /// Mass of a trails node
-        /// </summary>
-        public float TrailNodeMass { get; set; }
-
-        /// <summary>
-        /// Controls how fast the gamepad moves the cursor. 
-        /// Measured in pixels per second.
-        /// </summary>
-        public float CursorSpeed { get; set; }
-
-        /// <summary>
-        /// The scaling applied at the tip of the cursor
-        /// </summary>
-        public float StartScale { get; set; }
-        /// <summary>
-        /// The scaling applied at the end of the cursor
-        /// </summary>
-        public float EndScale { get; set; }
-
-        /// <summary>
-        /// use this to control the rate of change between the 
-        /// StartScale and the EndScale
-        /// </summary>
-        public float LerpExponent { get; set; }
-
-        /// <summary>
-        /// Color used to fill the cursor
-        /// </summary>
-        public Color FillColor { get; set; }
-
-        /// <summary>
-        /// color used for the cursor border
-        /// </summary>
-        public Color BorderColor { get; set; }
-
-        /// <summary>
-        /// Size of the border (in pixels)
-        /// </summary>
-        public float BorderSize { get; set; }
-
-
-        #endregion
-
-        #region Creation and initialization
-
-        public Cursor(Game game, int trailNodesNo, float stiffness, float damping)
-            :base(game)
-        {
-            trailNodeCount = trailNodesNo;
-            TrailStiffness = stiffness;
-            TrailDamping = damping;
-
-            trailNodes = new TrailNode[trailNodeCount];
-            CursorSpeed = 600;
-            StartScale = 1.0f;
-            EndScale = 0.3f;
-            LerpExponent = 0.5f;
-            TrailNodeMass = 11.2f;
-
-            FillColor = Color.Black;
-            BorderColor = Color.White;
-            BorderSize = 10;
-        }
-
-        public Cursor(Game game, int trailNodesNo)
-            : this(game, trailNodesNo, 30000, 600)
-        {
-        }
-
-        public Cursor(Game game)
-            : this(game,50,30000,600)
-        {
-        }
-
-        protected override void LoadContent()
-        {
-            cursorTexture = Game.Content.Load<Texture2D>("cursor");
-
-            textureCenter = new Vector2(cursorTexture.Width / 2, cursorTexture.Height / 2);
-
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-
-            base.LoadContent();
-        }
-
-        //we can center the cursor once we
-        //know how big the viewport will be
-        //this only really effects the 360 code
-        //where no mouse is available
-        public override void Initialize()
-        {            
-            base.Initialize();
-
-            Viewport vp = GraphicsDevice.Viewport;
-
-            position.X = vp.X + (vp.Width / 2);
-            position.Y = vp.Y + (vp.Height / 2);
-        }
-
-        #endregion
-
-        #region Draw
-
-        public override void Draw(GameTime gameTime)
-        {
-
-            //spriteBatch.Begin SpriteBlendMode.AlphaBlend);
-            //spriteBatch.Begin(0, BlendState.AlphaBlend);
-            spriteBatch.Begin ();
-            //First we draw all the trail nodes using the border color
-            //we need to draw them slightly larger, so the border is left visible
-            //later, when we draw the actual nodes
-
-            //adjust the StartScale and EndScale to take into consideration the border
-            float borderStartScale = StartScale  + BorderSize / cursorTexture.Width;
-            float borderEndScale = EndScale + BorderSize / cursorTexture.Width;
-
-            //draw all nodes with the new scales
-            for (int i = 0; i < trailNodeCount; i++)
-            {
-                TrailNode node = trailNodes[i];
-                float lerpFactor = (float)i / (float)(trailNodeCount - 1);
-                lerpFactor = (float)Math.Pow(lerpFactor, LerpExponent);
-                float scale = MathHelper.Lerp(borderStartScale, borderEndScale, lerpFactor);
-                
-                //draw using the Border Color
-                spriteBatch.Draw(cursorTexture, node.Position, null, BorderColor, 0.0f,
-                    textureCenter, scale, SpriteEffects.None, 0.0f);
-            }
-
-            //Next, we draw all the nodes normally, using the Fill Color
-            //Because before we drew them larger, after we draw them at
-            //their normal size, a border will remain visible.
-            for (int i = 0; i < trailNodeCount; i++)
-            {
-                TrailNode node = trailNodes[i];
-                float lerpFactor = (float)i / (float)(trailNodeCount - 1);
-                lerpFactor = (float)Math.Pow(lerpFactor, LerpExponent);
-                float scale = MathHelper.Lerp(StartScale, EndScale, lerpFactor);
-                
-                //draw using the fill color
-                spriteBatch.Draw(cursorTexture, node.Position, null, FillColor, 0.0f,
-                    textureCenter, scale, SpriteEffects.None, 0.0f);
-            }
-            
-            spriteBatch.End();
-        }
-
-        #endregion
-
-        #region Update
-
-        Vector2 deltaMovement;
-
-        private void UpdateTrailNodes(float elapsed)
-        {
-            for (int i = 1; i < trailNodeCount; i++)
-            {
-                TrailNode tn = trailNodes[i];
-
-                // Calculate spring force
-                Vector2 stretch = tn.Position - trailNodes[i - 1].Position;
-                Vector2 force = -TrailStiffness * stretch - TrailDamping * tn.Velocity;
-
-                // Apply acceleration
-                Vector2 acceleration = force / TrailNodeMass;
-                tn.Velocity += acceleration * elapsed;
-
-                // Apply velocity
-                tn.Position += tn.Velocity * elapsed;
-                trailNodes[i] = tn;
-            }
-
-        }
-
-        public override void Update(GameTime gameTime)
-        {
-
-            // first, use the GamePad to update the cursor position
-
-            // down on the thumbstick is -1. however, in screen coordinates, values
-            // increase as they go down the screen. so, we have to flip the sign of the
-            // y component of delta.
-            deltaMovement = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left;
-            deltaMovement.Y *= -1;
-
-
-
-            #if !XBOX360
-            //use the mouse position as the cursor position
-            MouseState mouseState = Mouse.GetState();
-            position.X = mouseState.X;
-            position.Y = mouseState.Y;
-            #endif
-			Console.WriteLine(position);
-            // modify position using delta, the CursorSpeed, and
-            // the elapsed game time.
-            position += deltaMovement * CursorSpeed *
-                (float)gameTime.ElapsedGameTime.TotalSeconds;
-			
-
-            #if XBOX360
-            // clamp the cursor position to the viewport, so that it can't move off the
-            // screen.
-            Viewport vp = GraphicsDevice.Viewport;
-            position.X = MathHelper.Clamp(position.X, vp.X, vp.X + vp.Width);
-            position.Y = MathHelper.Clamp(position.Y, vp.Y, vp.Y + vp.Height);
-            #else
-            // set the new mouse position using the combination of mouse and gamepad data.
-            Mouse.SetPosition((int)position.X, (int)position.Y);    
-            #endif
-
-
-            //set position of first trail node;
-            trailNodes[0].Position = position;
-            //update the trails
-            UpdateTrailNodes((float)gameTime.ElapsedGameTime.TotalSeconds);
-        }
-
-        #endregion
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Input;
+
+namespace GooCursor
+{
+    public class Cursor : DrawableGameComponent
+    {
+        private struct TrailNode
+        {
+            public Vector2 Position;
+            public Vector2 Velocity;
+        }
+
+        // this is the sprite that is drawn at the current cursor position.
+        // textureCenter is used to center the sprite when drawing.
+        private Texture2D cursorTexture;
+        private Vector2 textureCenter;
+        private SpriteBatch spriteBatch;
+
+        private Vector2 position;
+        private int trailNodeCount;
+        private TrailNode[] trailNodes;
+
+
+        /// <summary>
+        /// Gets of Sets the screen position of the cursor
+        /// </summary>
+        public Vector2 Position
+        {
+            get { return position; }
+            set { position = value; }
+        }
+        /// <summary>
+        /// Gets of Sets the stiffness of the trail
+        /// A lower number means the trail will be longer
+        /// </summary>
+        public float TrailStiffness { get; set; }
+
+        /// <summary>
+        /// Controls the damping of the velocity of trail nodes
+        /// </summary>
+        public float TrailDamping { get; set; }
+
+        /// <summary>
+        /// Mass of a trails node
+        /// </summary>
+        public float TrailNodeMass { get; set; }
+
+        /// <summary>
+        /// Controls how fast the gamepad moves the cursor. 
+        /// Measured in pixels per second.
+        /// </summary>
+        public float CursorSpeed { get; set; }
+
+        /// <summary>
+        /// The scaling applied at the tip of the cursor
+        /// </summary>
+        public float StartScale { get; set; }
+        /// <summary>
+        /// The scaling applied at the end of the cursor
+        /// </summary>
+        public float EndScale { get; set; }
+
+        /// <summary>
+        /// use this to control the rate of change between the 
+        /// StartScale and the EndScale
+        /// </summary>
+        public float LerpExponent { get; set; }
+
+        /// <summary>
+        /// Color used to fill the cursor
+        /// </summary>
+        public Color FillColor { get; set; }
+
+        /// <summary>
+        /// color used for the cursor border
+        /// </summary>
+        public Color BorderColor { get; set; }
+
+        /// <summary>
+        /// Size of the border (in pixels)
+        /// </summary>
+        public float BorderSize { get; set; }
+
+
+
+
+        public Cursor(Game game, int trailNodesNo, float stiffness, float damping)
+            :base(game)
+        {
+            trailNodeCount = trailNodesNo;
+            TrailStiffness = stiffness;
+            TrailDamping = damping;
+
+            trailNodes = new TrailNode[trailNodeCount];
+            CursorSpeed = 600;
+            StartScale = 1.0f;
+            EndScale = 0.3f;
+            LerpExponent = 0.5f;
+            TrailNodeMass = 11.2f;
+
+            FillColor = Color.Black;
+            BorderColor = Color.White;
+            BorderSize = 10;
+        }
+
+        public Cursor(Game game, int trailNodesNo)
+            : this(game, trailNodesNo, 30000, 600)
+        {
+        }
+
+        public Cursor(Game game)
+            : this(game,50,30000,600)
+        {
+        }
+
+        protected override void LoadContent()
+        {
+            cursorTexture = Game.Content.Load<Texture2D>("cursor");
+
+            textureCenter = new Vector2(cursorTexture.Width / 2, cursorTexture.Height / 2);
+
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+
+            base.LoadContent();
+        }
+
+        //we can center the cursor once we
+        //know how big the viewport will be
+        //this only really effects the 360 code
+        //where no mouse is available
+        public override void Initialize()
+        {            
+            base.Initialize();
+
+            Viewport vp = GraphicsDevice.Viewport;
+
+            position.X = vp.X + (vp.Width / 2);
+            position.Y = vp.Y + (vp.Height / 2);
+        }
+
+
+
+        public override void Draw(GameTime gameTime)
+        {
+
+            //spriteBatch.Begin SpriteBlendMode.AlphaBlend);
+            //spriteBatch.Begin(0, BlendState.AlphaBlend);
+            spriteBatch.Begin ();
+            //First we draw all the trail nodes using the border color
+            //we need to draw them slightly larger, so the border is left visible
+            //later, when we draw the actual nodes
+
+            //adjust the StartScale and EndScale to take into consideration the border
+            float borderStartScale = StartScale  + BorderSize / cursorTexture.Width;
+            float borderEndScale = EndScale + BorderSize / cursorTexture.Width;
+
+            //draw all nodes with the new scales
+            for (int i = 0; i < trailNodeCount; i++)
+            {
+                TrailNode node = trailNodes[i];
+                float lerpFactor = (float)i / (float)(trailNodeCount - 1);
+                lerpFactor = (float)Math.Pow(lerpFactor, LerpExponent);
+                float scale = MathHelper.Lerp(borderStartScale, borderEndScale, lerpFactor);
+                
+                //draw using the Border Color
+                spriteBatch.Draw(cursorTexture, node.Position, null, BorderColor, 0.0f,
+                    textureCenter, scale, SpriteEffects.None, 0.0f);
+            }
+
+            //Next, we draw all the nodes normally, using the Fill Color
+            //Because before we drew them larger, after we draw them at
+            //their normal size, a border will remain visible.
+            for (int i = 0; i < trailNodeCount; i++)
+            {
+                TrailNode node = trailNodes[i];
+                float lerpFactor = (float)i / (float)(trailNodeCount - 1);
+                lerpFactor = (float)Math.Pow(lerpFactor, LerpExponent);
+                float scale = MathHelper.Lerp(StartScale, EndScale, lerpFactor);
+                
+                //draw using the fill color
+                spriteBatch.Draw(cursorTexture, node.Position, null, FillColor, 0.0f,
+                    textureCenter, scale, SpriteEffects.None, 0.0f);
+            }
+            
+            spriteBatch.End();
+        }
+
+
+
+        Vector2 deltaMovement;
+
+        private void UpdateTrailNodes(float elapsed)
+        {
+            for (int i = 1; i < trailNodeCount; i++)
+            {
+                TrailNode tn = trailNodes[i];
+
+                // Calculate spring force
+                Vector2 stretch = tn.Position - trailNodes[i - 1].Position;
+                Vector2 force = -TrailStiffness * stretch - TrailDamping * tn.Velocity;
+
+                // Apply acceleration
+                Vector2 acceleration = force / TrailNodeMass;
+                tn.Velocity += acceleration * elapsed;
+
+                // Apply velocity
+                tn.Position += tn.Velocity * elapsed;
+                trailNodes[i] = tn;
+            }
+
+        }
+
+        public override void Update(GameTime gameTime)
+        {
+
+            // first, use the GamePad to update the cursor position
+
+            // down on the thumbstick is -1. however, in screen coordinates, values
+            // increase as they go down the screen. so, we have to flip the sign of the
+            // y component of delta.
+            deltaMovement = GamePad.GetState(PlayerIndex.One).ThumbSticks.Left;
+            deltaMovement.Y *= -1;
+
+
+
+            #if !XBOX360
+            //use the mouse position as the cursor position
+            MouseState mouseState = Mouse.GetState();
+            position.X = mouseState.X;
+            position.Y = mouseState.Y;
+            #endif
+			Console.WriteLine(position);
+            // modify position using delta, the CursorSpeed, and
+            // the elapsed game time.
+            position += deltaMovement * CursorSpeed *
+                (float)gameTime.ElapsedGameTime.TotalSeconds;
+			
+
+            #if XBOX360
+            // clamp the cursor position to the viewport, so that it can't move off the
+            // screen.
+            Viewport vp = GraphicsDevice.Viewport;
+            position.X = MathHelper.Clamp(position.X, vp.X, vp.X + vp.Width);
+            position.Y = MathHelper.Clamp(position.Y, vp.Y, vp.Y + vp.Height);
+            #else
+            // set the new mouse position using the combination of mouse and gamepad data.
+            Mouse.SetPosition((int)position.X, (int)position.Y);    
+            #endif
+
+
+            //set position of first trail node;
+            trailNodes[0].Position = position;
+            //update the trails
+            UpdateTrailNodes((float)gameTime.ElapsedGameTime.TotalSeconds);
+        }
+
+    }
+}

+ 159 - 163
GooCursor/Game1.cs → GooCursor/Core/Game1.cs

@@ -1,163 +1,159 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.GamerServices;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Xna.Framework.Net;
-using Microsoft.Xna.Framework.Storage;
-
-namespace GooCursor
-{
-    /// <summary>
-    /// This is the main type for your game
-    /// </summary>
-    public class Game1 : Microsoft.Xna.Framework.Game
-    {
-        GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-        SpriteFont spriteFont;
-        Cursor cursor;
-        public Game1()
-        {
-            graphics = new GraphicsDeviceManager(this);
-            Content.RootDirectory = "Content";
-            cursor = new Cursor(this,10);
-            cursor.BorderColor = Color.White;
-            cursor.FillColor = Color.Black;
-            Components.Add(cursor);
-			//graphics.IsFullScreen = true;
-			//IsMouseVisible = false;
-        }
-
-        /// <summary>
-        /// Allows the game to perform any initialization it needs to before starting to run.
-        /// This is where it can query for any required services and load any non-graphic
-        /// related content.  Calling base.Initialize will enumerate through any components
-        /// and initialize them as well.
-        /// </summary>
-        protected override void Initialize()
-        {
-            // TODO: Add your initialization logic here
-
-            base.Initialize();
-        }
-
-        /// <summary>
-        /// LoadContent will be called once per game and is the place to load
-        /// all of your content.
-        /// </summary>
-        protected override void LoadContent()
-        {
-            // Create a new SpriteBatch, which can be used to draw textures.
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-            spriteFont = Content.Load<SpriteFont>("SimpleFont");
-        }
-
-        /// <summary>
-        /// UnloadContent will be called once per game and is the place to unload
-        /// all content.
-        /// </summary>
-        protected override void UnloadContent()
-        {
-            // TODO: Unload any non ContentManager content here
-        }
-		KeyboardState lastState = Keyboard.GetState();
-		KeyboardState state = Keyboard.GetState();
-
-        /// <summary>
-        /// Allows the game to run logic such as updating the world,
-        /// checking for collisions, gathering input, and playing audio.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        protected override void Update(GameTime gameTime)
-        {
-            // Allows the game to exit
-            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
-                this.Exit();
-			lastState = state;
-			state = Keyboard.GetState();
-
-
-            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
-
-            if (state.IsKeyDown(Keys.Q))
-                cursor.StartScale += 1.0f * elapsed;
-            if (state.IsKeyDown(Keys.A))
-                cursor.StartScale -= 1.0f * elapsed;
-
-
-            if (state.IsKeyDown(Keys.W))
-                cursor.EndScale += 1.0f * elapsed;
-            if (state.IsKeyDown(Keys.S))
-                cursor.EndScale -= 1.0f * elapsed;
-
-
-            if (state.IsKeyDown(Keys.E))
-                cursor.LerpExponent += 1.0f * elapsed;
-            if (state.IsKeyDown(Keys.D))
-                cursor.LerpExponent -= 1.0f * elapsed;
-
-            if (state.IsKeyDown(Keys.R))
-                cursor.BorderSize += 10.0f * elapsed;
-            if (state.IsKeyDown(Keys.F))
-                cursor.BorderSize -= 10.0f * elapsed;
-
-
-            if (state.IsKeyDown(Keys.T))
-                cursor.TrailStiffness += 1000.0f * elapsed;
-            if (state.IsKeyDown(Keys.G))
-                cursor.TrailStiffness -= 1000.0f * elapsed;
-
-
-            if (state.IsKeyDown(Keys.Y))
-                cursor.TrailDamping += 100.0f * elapsed;
-            if (state.IsKeyDown(Keys.H))
-                cursor.TrailDamping -= 100.0f * elapsed;
-
-
-            if (state.IsKeyDown(Keys.U))
-                cursor.TrailNodeMass += 1.0f * elapsed;
-            if (state.IsKeyDown(Keys.J))
-                cursor.TrailNodeMass -= 1.0f * elapsed;
-
-		if (state.IsKeyDown(Keys.F) && lastState.IsKeyUp(Keys.F))
-				graphics.ToggleFullScreen();
-
-            base.Update(gameTime);
-        }
-
-        /// <summary>
-        /// This is called when the game should draw itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        protected override void Draw(GameTime gameTime)
-        {
-            GraphicsDevice.Clear(Color.CornflowerBlue);
-
-            base.Draw(gameTime);
-
-            spriteBatch.Begin();
-            DrawString("[Q/A] Start Scale   : " + cursor.StartScale, new Vector2(20, 20));
-            DrawString("[W/S] End Scale     : " + cursor.EndScale, new Vector2(20, 40));
-            DrawString("[E/D] Lerp Exponent : " + cursor.LerpExponent, new Vector2(20, 60));
-            DrawString("[R/F] Border Size   : " + cursor.BorderSize, new Vector2(20, 80));
-
-            DrawString("[T/G] Stiffness     : " + cursor.TrailStiffness, new Vector2(400, 20));
-            DrawString("[Y/H] Damping       : " + cursor.TrailDamping, new Vector2(400, 40));
-            DrawString("[U/J] Node Mass     : " + cursor.TrailNodeMass, new Vector2(400, 60));
-
-            spriteBatch.End();
-        }
-
-        private void DrawString(String text, Vector2 position)
-        {
-            spriteBatch.DrawString(spriteFont, text, position + new Vector2(1, 1), Color.Black);
-            spriteBatch.DrawString(spriteFont, text, position , Color.White);
-        }
-    }
-}
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+
+namespace GooCursor
+{
+    /// <summary>
+    /// This is the main type for your game
+    /// </summary>
+    public class Game1 : Microsoft.Xna.Framework.Game
+    {
+        GraphicsDeviceManager graphics;
+        SpriteBatch spriteBatch;
+        SpriteFont spriteFont;
+        Cursor cursor;
+        public Game1()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+            cursor = new Cursor(this,10);
+            cursor.BorderColor = Color.White;
+            cursor.FillColor = Color.Black;
+            Components.Add(cursor);
+			//graphics.IsFullScreen = true;
+			//IsMouseVisible = false;
+        }
+
+        /// <summary>
+        /// Allows the game to perform any initialization it needs to before starting to run.
+        /// This is where it can query for any required services and load any non-graphic
+        /// related content.  Calling base.Initialize will enumerate through any components
+        /// and initialize them as well.
+        /// </summary>
+        protected override void Initialize()
+        {
+            // TODO: Add your initialization logic here
+
+            base.Initialize();
+        }
+
+        /// <summary>
+        /// LoadContent will be called once per game and is the place to load
+        /// all of your content.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            // Create a new SpriteBatch, which can be used to draw textures.
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            spriteFont = Content.Load<SpriteFont>("SimpleFont");
+        }
+
+        /// <summary>
+        /// UnloadContent will be called once per game and is the place to unload
+        /// all content.
+        /// </summary>
+        protected override void UnloadContent()
+        {
+            // TODO: Unload any non ContentManager content here
+        }
+		KeyboardState lastState = Keyboard.GetState();
+		KeyboardState state = Keyboard.GetState();
+
+        /// <summary>
+        /// Allows the game to run logic such as updating the world,
+        /// checking for collisions, gathering input, and playing audio.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Update(GameTime gameTime)
+        {
+            lastState = state;
+            state = Keyboard.GetState();
+
+            // Allows the game to exit
+            if (state.IsKeyDown(Keys.Escape) ||
+                GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
+                this.Exit();
+
+
+            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+            if (state.IsKeyDown(Keys.Q))
+                cursor.StartScale += 1.0f * elapsed;
+            if (state.IsKeyDown(Keys.A))
+                cursor.StartScale -= 1.0f * elapsed;
+
+
+            if (state.IsKeyDown(Keys.W))
+                cursor.EndScale += 1.0f * elapsed;
+            if (state.IsKeyDown(Keys.S))
+                cursor.EndScale -= 1.0f * elapsed;
+
+
+            if (state.IsKeyDown(Keys.E))
+                cursor.LerpExponent += 1.0f * elapsed;
+            if (state.IsKeyDown(Keys.D))
+                cursor.LerpExponent -= 1.0f * elapsed;
+
+            if (state.IsKeyDown(Keys.R))
+                cursor.BorderSize += 10.0f * elapsed;
+            if (state.IsKeyDown(Keys.F))
+                cursor.BorderSize -= 10.0f * elapsed;
+
+
+            if (state.IsKeyDown(Keys.T))
+                cursor.TrailStiffness += 1000.0f * elapsed;
+            if (state.IsKeyDown(Keys.G))
+                cursor.TrailStiffness -= 1000.0f * elapsed;
+
+
+            if (state.IsKeyDown(Keys.Y))
+                cursor.TrailDamping += 100.0f * elapsed;
+            if (state.IsKeyDown(Keys.H))
+                cursor.TrailDamping -= 100.0f * elapsed;
+
+
+            if (state.IsKeyDown(Keys.U))
+                cursor.TrailNodeMass += 1.0f * elapsed;
+            if (state.IsKeyDown(Keys.J))
+                cursor.TrailNodeMass -= 1.0f * elapsed;
+
+            if (state.IsKeyDown(Keys.LeftShift)
+            && state.IsKeyDown(Keys.Enter)
+            && lastState.IsKeyUp(Keys.Enter))
+                graphics.ToggleFullScreen();
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// This is called when the game should draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.Clear(Color.CornflowerBlue);
+
+            base.Draw(gameTime);
+
+            spriteBatch.Begin();
+            DrawString("[Q/A] Start Scale   : " + cursor.StartScale, new Vector2(20, 20));
+            DrawString("[W/S] End Scale     : " + cursor.EndScale, new Vector2(20, 40));
+            DrawString("[E/D] Lerp Exponent : " + cursor.LerpExponent, new Vector2(20, 60));
+            DrawString("[R/F] Border Size   : " + cursor.BorderSize, new Vector2(20, 80));
+
+            DrawString("[T/G] Stiffness     : " + cursor.TrailStiffness, new Vector2(400, 20));
+            DrawString("[Y/H] Damping       : " + cursor.TrailDamping, new Vector2(400, 40));
+            DrawString("[U/J] Node Mass     : " + cursor.TrailNodeMass, new Vector2(400, 60));
+
+            spriteBatch.End();
+        }
+
+        private void DrawString(String text, Vector2 position)
+        {
+            spriteBatch.DrawString(spriteFont, text, position + new Vector2(1, 1), Color.Black);
+            spriteBatch.DrawString(spriteFont, text, position , Color.White);
+        }
+    }
+}

+ 8 - 0
GooCursor/Core/GooCursor.Core.csproj

@@ -0,0 +1,8 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+</Project>

+ 0 - 71
GooCursor/GooCursor.Linux.csproj

@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{EA7CF275-795B-4385-80AA-C41DA3B9B0F9}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>GooCursor</RootNamespace>
-    <AssemblyName>GooCursor</AssemblyName>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>False</ConsolePause>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>False</ConsolePause>
-  </PropertyGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <Reference Include="System" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Cursor.cs">
-      <Link>Cursor.cs</Link>
-    </Compile>
-    <Compile Include="Game1.cs">
-      <Link>Game1.cs</Link>
-    </Compile>
-    <Compile Include="Program.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Game.ico">
-      <Link>Game.ico</Link>
-    </None>
-    <None Include="GameThumbnail.png">
-      <Link>GameThumbnail.png</Link>
-    </None>
-    <None Include="Readme.md">
-      <Link>Readme.md</Link>
-    </None>
-    <None Include="Content\SimpleFont.spritefont">
-      <Link>Content\SimpleFont.spritefont</Link>
-    </None>
-    <None Include="Content\cursor.bmp">
-      <Link>Content\cursor.bmp</Link>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Content\SimpleFont.xnb">
-      <Link>Content\SimpleFont.xnb</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="Content\cursor.xnb">
-      <Link>Content\cursor.xnb</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-  </ItemGroup>
-</Project>

+ 0 - 85
GooCursor/GooCursor.MacOS.csproj

@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{18E6467D-47C4-47CA-8CD1-508AD311C054}</ProjectGuid>
-    <ProjectTypeGuids>{948B3504-5B70-4649-8FE4-BDE1FB46EC69};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>GooCursor</RootNamespace>
-    <AssemblyName>GooCursor</AssemblyName>
-    <SuppressXamMacUpsell>True</SuppressXamMacUpsell>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;MONOMAC</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <ConsolePause>False</ConsolePause>
-    <EnableCodeSigning>False</EnableCodeSigning>
-    <CreatePackage>False</CreatePackage>
-    <EnablePackageSigning>False</EnablePackageSigning>
-    <IncludeMonoRuntime>False</IncludeMonoRuntime>
-    <UseSGen>False</UseSGen>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>none</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <ConsolePause>False</ConsolePause>
-    <EnableCodeSigning>False</EnableCodeSigning>
-    <CreatePackage>False</CreatePackage>
-    <EnablePackageSigning>False</EnablePackageSigning>
-    <IncludeMonoRuntime>False</IncludeMonoRuntime>
-    <DefineConstants>MONOMAC</DefineConstants>
-    <UseSGen>False</UseSGen>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="MonoMac" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Info.plist">
-    </None>
-    <None Include="Content\SimpleFont.spritefont" />
-    <None Include="Content\cursor.bmp" />
-    <None Include="Game.ico" />
-    <None Include="GameThumbnail.png" />
-    <None Include="Readme.md" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
-  <ItemGroup>
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Cursor.cs" />
-    <Compile Include="Game1.cs" />
-    <Compile Include="Program.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Content\SimpleFont.xnb" />
-    <Content Include="Content\cursor.xnb" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
-      <Project>{36C538E6-C32A-4A8D-A39C-566173D7118E}</Project>
-      <Name>MonoGame.Framework.MacOS</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj">
-      <Project>{AE483C29-042E-4226-BA52-D247CE7676DA}</Project>
-      <Name>Lidgren.Network.MacOS</Name>
-    </ProjectReference>
-  </ItemGroup>
-</Project>

+ 52 - 29
GooCursor/GooCursor.sln

@@ -1,35 +1,58 @@
 
 
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor", "GooCursor.csproj", "{18E6467D-47C4-47CA-8CD1-508AD311C054}"
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor.Core", "Core\GooCursor.Core.csproj", "{E1E6467D-47C4-47CA-8CD1-508AD311C054}"
 EndProject
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network.MacOS", "..\..\..\..\..\..\..\Users\Jimmy\Public\Share\MonoMacSource\kjpgit\MonoGame\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj", "{AE483C29-042E-4226-BA52-D247CE7676DA}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor.Windows", "Platforms\Windows\GooCursor.Windows.csproj", "{18E6467D-47C4-47CA-8CD1-508AD311C054}"
 EndProject
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.MacOS", "..\..\..\..\..\..\..\Users\Jimmy\Public\Share\MonoMacSource\kjpgit\MonoGame\MonoGame.Framework\MonoGame.Framework.MacOS.csproj", "{36C538E6-C32A-4A8D-A39C-566173D7118E}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor.DesktopGL", "Platforms\Desktop\GooCursor.DesktopGL.csproj", "{A7C02F2B-8B23-4F6A-9E71-9B9F6A9E3B4C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor.Linux", "Platforms\Linux\GooCursor.Linux.csproj", "{EA7CF275-795B-4385-80AA-C41DA3B9B0F9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor.MacOS", "Platforms\MacOS\GooCursor.MacOS.csproj", "{B8F6D3C1-9A4E-4F8B-8E2A-1C2D3E4F5A6B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor.iOS", "Platforms\iOS\GooCursor.iOS.csproj", "{C9G7E4D2-AB5F-4G9C-9F3B-2D3E4F5A6B7C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GooCursor.Android", "Platforms\Android\GooCursor.Android.csproj", "{D1H8F5E3-BC6G-4H1D-1G4C-3E4F5A6B7C8D}"
 EndProject
 EndProject
 Global
 Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|x86 = Debug|x86
-		Release|x86 = Release|x86
-		Distribution|Any CPU = Distribution|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{18E6467D-47C4-47CA-8CD1-508AD311C054}.Debug|x86.ActiveCfg = Debug|x86
-		{18E6467D-47C4-47CA-8CD1-508AD311C054}.Debug|x86.Build.0 = Debug|x86
-		{18E6467D-47C4-47CA-8CD1-508AD311C054}.Release|x86.ActiveCfg = Release|x86
-		{18E6467D-47C4-47CA-8CD1-508AD311C054}.Release|x86.Build.0 = Release|x86
-		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Debug|x86.Build.0 = Debug|Any CPU
-		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Distribution|Any CPU.ActiveCfg = Distribution|Any CPU
-		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Distribution|Any CPU.Build.0 = Distribution|Any CPU
-		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Release|x86.ActiveCfg = Release|Any CPU
-		{36C538E6-C32A-4A8D-A39C-566173D7118E}.Release|x86.Build.0 = Release|Any CPU
-		{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{AE483C29-042E-4226-BA52-D247CE7676DA}.Debug|x86.Build.0 = Debug|Any CPU
-		{AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.ActiveCfg = Release|Any CPU
-		{AE483C29-042E-4226-BA52-D247CE7676DA}.Release|x86.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(MonoDevelopProperties) = preSolution
-		StartupItem = GooCursor.csproj
-	EndGlobalSection
+	   GlobalSection(SolutionConfigurationPlatforms) = preSolution
+			   Debug|Any CPU = Debug|Any CPU
+			   Release|Any CPU = Release|Any CPU
+	   EndGlobalSection
+	   GlobalSection(ProjectConfigurationPlatforms) = postSolution
+			   {E1E6467D-47C4-47CA-8CD1-508AD311C054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+			   {E1E6467D-47C4-47CA-8CD1-508AD311C054}.Debug|Any CPU.Build.0 = Debug|Any CPU
+			   {E1E6467D-47C4-47CA-8CD1-508AD311C054}.Release|Any CPU.ActiveCfg = Release|Any CPU
+			   {E1E6467D-47C4-47CA-8CD1-508AD311C054}.Release|Any CPU.Build.0 = Release|Any CPU
+			   {18E6467D-47C4-47CA-8CD1-508AD311C054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+			   {18E6467D-47C4-47CA-8CD1-508AD311C054}.Debug|Any CPU.Build.0 = Debug|Any CPU
+			   {18E6467D-47C4-47CA-8CD1-508AD311C054}.Release|Any CPU.ActiveCfg = Release|Any CPU
+			   {18E6467D-47C4-47CA-8CD1-508AD311C054}.Release|Any CPU.Build.0 = Release|Any CPU
+			   {A7C02F2B-8B23-4F6A-9E71-9B9F6A9E3B4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+			   {A7C02F2B-8B23-4F6A-9E71-9B9F6A9E3B4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+			   {A7C02F2B-8B23-4F6A-9E71-9B9F6A9E3B4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+			   {A7C02F2B-8B23-4F6A-9E71-9B9F6A9E3B4C}.Release|Any CPU.Build.0 = Release|Any CPU
+			   {EA7CF275-795B-4385-80AA-C41DA3B9B0F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+			   {EA7CF275-795B-4385-80AA-C41DA3B9B0F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+			   {EA7CF275-795B-4385-80AA-C41DA3B9B0F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+			   {EA7CF275-795B-4385-80AA-C41DA3B9B0F9}.Release|Any CPU.Build.0 = Release|Any CPU
+			   {B8F6D3C1-9A4E-4F8B-8E2A-1C2D3E4F5A6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+			   {B8F6D3C1-9A4E-4F8B-8E2A-1C2D3E4F5A6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+			   {B8F6D3C1-9A4E-4F8B-8E2A-1C2D3E4F5A6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+			   {B8F6D3C1-9A4E-4F8B-8E2A-1C2D3E4F5A6B}.Release|Any CPU.Build.0 = Release|Any CPU
+			   {C9G7E4D2-AB5F-4G9C-9F3B-2D3E4F5A6B7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+			   {C9G7E4D2-AB5F-4G9C-9F3B-2D3E4F5A6B7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+			   {C9G7E4D2-AB5F-4G9C-9F3B-2D3E4F5A6B7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+			   {C9G7E4D2-AB5F-4G9C-9F3B-2D3E4F5A6B7C}.Release|Any CPU.Build.0 = Release|Any CPU
+			   {D1H8F5E3-BC6G-4H1D-1G4C-3E4F5A6B7C8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+			   {D1H8F5E3-BC6G-4H1D-1G4C-3E4F5A6B7C8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+			   {D1H8F5E3-BC6G-4H1D-1G4C-3E4F5A6B7C8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+			   {D1H8F5E3-BC6G-4H1D-1G4C-3E4F5A6B7C8D}.Release|Any CPU.Build.0 = Release|Any CPU
+	   EndGlobalSection
+	   GlobalSection(SolutionProperties) = preSolution
+			   HideSolutionNode = FALSE
+	   EndGlobalSection
 EndGlobal
 EndGlobal

+ 27 - 0
GooCursor/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          android:versionCode="1"
+          android:versionName="1.0"
+          package="com.goocursor.android">
+  
+  <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
+
+  <application android:allowBackup="true"
+               android:label="GooCursor"
+               android:hardwareAccelerated="true">
+               
+    <activity android:name="crc6477f0d89a9cfd64b1.MainActivity"
+              android:exported="true"
+              android:launchMode="singleInstance"
+              android:screenOrientation="fullUser"
+              android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
+              android:windowSoftInputMode="adjustPan">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+  
+  <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+</manifest>

+ 22 - 0
GooCursor/Platforms/Android/GooCursor.Android.csproj

@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
+    <AndroidUseAapt2>true</AndroidUseAapt2>
+    <AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
+    <EnableMGCBItems>false</EnableMGCBItems>
+    <DefineConstants>ANDROID</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="../../Core/GooCursor.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+</Project>

+ 34 - 0
GooCursor/Platforms/Android/MainActivity.cs

@@ -0,0 +1,34 @@
+#if ANDROID
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Android.Views;
+using Microsoft.Xna.Framework;
+
+namespace GooCursor
+{
+    [Activity(
+        Label = "GooCursor",
+        MainLauncher = true,
+        AlwaysRetainTaskState = true,
+        LaunchMode = LaunchMode.SingleInstance,
+        ScreenOrientation = ScreenOrientation.FullUser,
+        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize)]
+    public class MainActivity : AndroidGameActivity
+    {
+        private Game1 game;
+        private View gameView;
+
+        protected override void OnCreate(Bundle bundle)
+        {
+            base.OnCreate(bundle);
+
+            game = new Game1();
+            gameView = game.Services.GetService(typeof(View)) as View;
+
+            SetContentView(gameView);
+            game.Run();
+        }
+    }
+}
+#endif

+ 23 - 0
GooCursor/Platforms/Desktop/GooCursor.DesktopGL.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <EnableMGCBItems>false</EnableMGCBItems>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationIcon>../../Core/Content/Game.ico</ApplicationIcon>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="../../Core/GooCursor.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 14 - 0
GooCursor/Platforms/Desktop/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace GooCursor.Platforms.Desktop
+{
+    static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            var game = new GooCursor.Game1();
+            game.Run();
+        }
+    }
+}

+ 0 - 0
GooCursor/Platforms/Linux/GooCursor.Linux.csproj


+ 0 - 0
GooCursor/Platforms/MacOS/GooCursor.MacOS.csproj


+ 25 - 0
GooCursor/Platforms/Windows/GooCursor.Windows.csproj

@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <UseWindowsForms>true</UseWindowsForms>
+    <EnableMGCBItems>false</EnableMGCBItems>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationManifest>app.manifest</ApplicationManifest>
+    <ApplicationIcon>../../Core/Content/Game.ico</ApplicationIcon>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="../../Core/GooCursor.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 14 - 0
GooCursor/Platforms/Windows/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace GooCursor.Platforms.Windows
+{
+    static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            var game = new GooCursor.Game1();
+            game.Run();
+        }
+    }
+}

+ 43 - 0
GooCursor/Platforms/Windows/app.manifest

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+  <assemblyIdentity version="1.0.0.0" name="GooCursor"/>
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+    <security>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+
+  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+    <application>
+      <!-- A list of the Windows versions that this application has been tested on and is
+           is designed to work with. Uncomment the appropriate elements and Windows will 
+           automatically selected the most compatible environment. -->
+
+      <!-- Windows Vista -->
+      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
+
+      <!-- Windows 7 -->
+      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
+
+      <!-- Windows 8 -->
+      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
+
+      <!-- Windows 8.1 -->
+      <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
+
+      <!-- Windows 10 -->
+      <!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
+
+    </application>
+  </compatibility>
+
+  <application xmlns="urn:schemas-microsoft-com:asm.v3">
+    <windowsSettings>
+      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
+    </windowsSettings>
+  </application>
+
+</assembly>

+ 22 - 0
GooCursor/Platforms/iOS/GooCursor.iOS.csproj

@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RollForward>Major</RollForward>
+    <PublishReadyToRun>false</PublishReadyToRun>
+    <TieredCompilation>false</TieredCompilation>
+    <UseInterpreter>false</UseInterpreter>
+    <SupportedOSPlatformVersion>11.0</SupportedOSPlatformVersion>
+    <EnableMGCBItems>false</EnableMGCBItems>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="../../Core/GooCursor.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 0 - 0
GooCursor/Info.plist → GooCursor/Platforms/iOS/Info.plist


+ 12 - 0
GooCursor/Platforms/iOS/Program.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace GooCursor.Platforms.iOS
+{
+    public class Program
+    {
+        static void Main(string[] args)
+        {
+            // iOS entry point logic here (stub)
+        }
+    }
+}

+ 0 - 65
GooCursor/Program.cs

@@ -1,65 +0,0 @@
-
-#region Using Statements
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-
-#if MONOMAC
-using MonoMac.Foundation;
-using MonoMac.AppKit;
-using MonoMac.ObjCRuntime;
-#endif
-
-#endregion
-
-namespace GooCursor
-{
-#if MONOMAC
-	static class Program
-	{
-		/// <summary>
-		/// The main entry point for the application.
-		/// </summary>
-		static void Main (string[] args)
-		{
-			NSApplication.Init ();
-			
-			using (var p = new NSAutoreleasePool ()) {
-				NSApplication.SharedApplication.Delegate = new AppDelegate();
-				NSApplication.Main(args);
-			}
-		}
-	}
-	
-	class AppDelegate : NSApplicationDelegate
-	{
-		Game1 game;
-		public override void FinishedLaunching (MonoMac.Foundation.NSObject notification)
-		{
-			game = new Game1();
-			game.Run();
-		}
-		
-		public override bool ApplicationShouldTerminateAfterLastWindowClosed (NSApplication sender)
-		{
-			return true;
-		}
-	}			
-#else
-    static class Program
-    {
-        private static Game1 game;
-
-        /// <summary>
-        /// The main entry point for the application.
-        /// </summary>
-        [STAThread]
-        static void Main()
-        {
-            game = new Game1();
-            game.Run();
-        }
-    }
-#endif
-}

+ 0 - 33
GooCursor/Properties/AssemblyInfo.cs

@@ -1,33 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("GooCursor")]
-[assembly: AssemblyProduct("GooCursor")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyCompany("")]
-
-[assembly: AssemblyCopyright("Copyright ©  2009")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("52ebd561-8dba-433b-86d5-067c0941702b")]
-
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyVersion("1.0.0.0")]

+ 56 - 3
GooCursor/Readme.md

@@ -1,7 +1,60 @@
 GooCursor
 GooCursor
 =========
 =========
 
 
-Shows an example of adding a custom cursor to your XNA projects.
+GooCursor is a cross-platform MonoGame sample demonstrating a custom, physics-based cursor inspired by World of Goo.
 
 
-Converted to XNA 4.0 by Kenneth J. Pouncey from the original article here: 
-http://www.catalinzima.com/samples/game-features-replicator/world-of-goo-cursor/
+## Supported Platforms
+- Windows (Desktop)
+- DesktopGL (Cross-platform)
+- Android
+- iOS
+
+## Desktop Controls
+
+| Key(s)                | Action                        |
+|-----------------------|-------------------------------|
+| Q / A                 | Increase / Decrease Start Scale |
+| W / S                 | Increase / Decrease End Scale   |
+| E / D                 | Increase / Decrease Lerp Exponent |
+| R / F                 | Increase / Decrease Border Size  |
+| T / G                 | Increase / Decrease Trail Stiffness |
+| Y / H                 | Increase / Decrease Trail Damping |
+| U / J                 | Increase / Decrease Trail Node Mass |
+| Left Shift + Enter    | Toggle Fullscreen               |
+
+## Project Structure
+- `/Core` — Shared game logic and assets (`Game1.cs`, `Cursor.cs`, etc.)
+- `/Platforms/<Platform>` — Platform-specific entry points and project files
+
+## How to Build & Run
+
+### Prerequisites
+- [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
+- [MonoGame 3.8.*](https://www.monogame.net/)
+- (Optional) Android/iOS build tools for mobile platforms
+
+### Windows & DesktopGL
+1. Open the solution (`GooCursor.sln`) in Visual Studio or VS Code.
+2. Select the desired platform project under `Platforms/` (e.g., `Platforms/Windows/GooCursor.Windows.csproj`).
+3. Build and run:
+   - **VS Code:** Use the provided tasks (`Ctrl+Shift+B`) or F5 to debug.
+   - **Command Line:**
+     - Windows: `dotnet run --project Platforms/Windows/GooCursor.Windows.csproj`
+     - DesktopGL: `dotnet run --project Platforms/Desktop/GooCursor.DesktopGL.csproj`
+
+### Android & iOS
+1. Open the solution in Visual Studio (Windows or Mac) or use the command line.
+2. Build the platform project:
+   - Android: `dotnet build Platforms/Android/GooCursor.Android.csproj`
+   - iOS: `dotnet build Platforms/iOS/GooCursor.iOS.csproj`
+3. Deploy to device/emulator as appropriate.
+
+### Linux & macOS
+1. Build the respective project:
+   - Linux: `dotnet run --project Platforms/Linux/GooCursor.Linux.csproj`
+   - macOS: `dotnet run --project Platforms/MacOS/GooCursor.MacOS.csproj`
+
+## Credits
+- Original concept: [Catalin Zima](http://www.catalinzima.com/samples/game-features-replicator/world-of-goo-cursor/)
+- XNA 4.0 port: Kenneth J. Pouncey
+- Modernization & cross-platform: CartBlanche