mirror of
https://github.com/livingcomputermuseum/ContrAlto.git
synced 2026-01-17 16:44:29 +00:00
187 lines
4.7 KiB
C#
187 lines
4.7 KiB
C#
using Contralto.CPU;
|
|
using Contralto.Memory;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
namespace Contralto.IO
|
|
{
|
|
[Flags]
|
|
public enum AltoMouseButton
|
|
{
|
|
None = 0x0,
|
|
Middle = 0x1,
|
|
Right = 0x2,
|
|
Left = 0x4,
|
|
}
|
|
|
|
public class Mouse : IMemoryMappedDevice
|
|
{
|
|
public Mouse()
|
|
{
|
|
_lock = new ReaderWriterLockSlim();
|
|
Reset();
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
// cheat for synchronization: this is approximately where the mouse is initialized to
|
|
// at alto boot.
|
|
_mouseY = 80;
|
|
_mouseX = 0;
|
|
}
|
|
|
|
public ushort Read(int address, TaskType task, bool extendedMemoryReference)
|
|
{
|
|
return (ushort)(~_buttons);
|
|
}
|
|
|
|
public void Load(int address, ushort data, TaskType task, bool extendedMemoryReference)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
public void MouseMove(int dx, int dy)
|
|
{
|
|
_lock.EnterWriteLock();
|
|
|
|
// Calculate number of steps in x and y to be decremented every call to PollMouseBits
|
|
_xSteps = Math.Abs(dx);
|
|
_xDir = Math.Sign(dx);
|
|
|
|
_ySteps = Math.Abs(dy);
|
|
_yDir = Math.Sign(dy);
|
|
|
|
//Console.WriteLine("Mouse move from ({0},{1}) to ({2},{3}).", _mouseX, _mouseY, _destX, _destY);
|
|
_lock.ExitWriteLock();
|
|
}
|
|
|
|
public void MouseDown(AltoMouseButton button)
|
|
{
|
|
_buttons |= button;
|
|
}
|
|
|
|
public void MouseUp(AltoMouseButton button)
|
|
{
|
|
_buttons ^= button;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the bits read by the "<-MOUSE" special function, and moves
|
|
/// the pointer one step closer to its final destination (if it has moved at all).
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public ushort PollMouseBits()
|
|
{
|
|
//
|
|
// The bits returned correspond to the delta incurred by mouse movement in the X and Y direction
|
|
// and map to:
|
|
// 0 : no change in X or Y
|
|
// 1 : dy = -1
|
|
// 2 : dy = 1
|
|
// 3 : dx = -1
|
|
// 4 : dy = -1, dx = -1
|
|
// 5 : dy = 1, dx = -1
|
|
// 6 : dx = 1
|
|
// 7 : dy = -1, dx = 1
|
|
// 8 : dy = 1, dx =1
|
|
ushort bits = 0;
|
|
|
|
_lock.EnterReadLock();
|
|
// TODO: optimize this
|
|
if (_yDir == -1 && _xDir == 0)
|
|
{
|
|
bits = 1;
|
|
}
|
|
else if (_yDir == 1 && _xDir == 0)
|
|
{
|
|
bits = 2;
|
|
}
|
|
else if (_yDir == 0 && _xDir == -1)
|
|
{
|
|
bits = 3;
|
|
}
|
|
else if (_yDir == -1 && _xDir == -1)
|
|
{
|
|
bits = 4;
|
|
}
|
|
else if (_yDir == 1 && _xDir == -1)
|
|
{
|
|
bits = 5;
|
|
}
|
|
else if (_yDir == 0 && _xDir == 1)
|
|
{
|
|
bits = 6;
|
|
}
|
|
else if (_yDir == -1 && _xDir == 1)
|
|
{
|
|
bits = 7;
|
|
}
|
|
else if (_yDir == 1 && _xDir == 1)
|
|
{
|
|
bits = 8;
|
|
}
|
|
|
|
//Console.WriteLine("Mouse poll: xdir {0}, ydir {1}, bits {2}", _xDir, _yDir, Conversion.ToOctal(bits));
|
|
|
|
// Move the mouse closer to its destination
|
|
if (_xSteps > 0)
|
|
{
|
|
_mouseX += _xDir;
|
|
_xSteps--;
|
|
|
|
if (_xSteps == 0)
|
|
{
|
|
_xDir = 0;
|
|
}
|
|
}
|
|
|
|
if (_ySteps > 0)
|
|
{
|
|
_mouseY += _yDir;
|
|
_ySteps--;
|
|
|
|
if (_ySteps == 0)
|
|
{
|
|
_yDir = 0;
|
|
}
|
|
}
|
|
_lock.ExitReadLock();
|
|
|
|
return bits;
|
|
}
|
|
|
|
public MemoryRange[] Addresses
|
|
{
|
|
get { return _addresses; }
|
|
}
|
|
|
|
private readonly MemoryRange[] _addresses =
|
|
{
|
|
new MemoryRange(0xfe18, 0xfe1b), // UTILIN: 177030-177033
|
|
};
|
|
|
|
// Mouse buttons:
|
|
AltoMouseButton _buttons;
|
|
|
|
/// <summary>
|
|
/// Where the mouse is currently reported to be
|
|
/// </summary>
|
|
private int _mouseX;
|
|
private int _mouseY;
|
|
|
|
/// <summary>
|
|
/// Where the mouse is moving to every time PollMouseBits is called.
|
|
/// </summary>
|
|
private int _xSteps;
|
|
private int _xDir;
|
|
private double _ySteps;
|
|
private int _yDir;
|
|
|
|
private ReaderWriterLockSlim _lock;
|
|
}
|
|
}
|
|
|