Weird GUI issue in cosmos - c#

When i do display.init() I get these white lines and a few other different pixels. The next thing that happens is they disappear one line at a time and it's preventing my VGA from booting.
I'll post my kernel code and display driver.
DISPLAY DRIVER C#
using Cosmos.HAL;
using Sys = Cosmos.System;
namespace Display
{
public class DisplayDriver
{
protected VGAScreen screen;
private int width, height;
public DisplayDriver()
{
screen = new VGAScreen();
}
public void init()
{
screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8);
screen.Clear(0);
width = screen.PixelWidth;
height = screen.PixelHeight;
}
public virtual void setPixel(int x, int y, int c)
{
if (screen.GetPixel320x200x8((uint)x, (uint)y) != (uint)c)
setPixelRaw(x, y, c);
}
public virtual byte getPixel(int x, int y)
{
return (byte)screen.GetPixel320x200x8((uint)x, (uint)y);
}
public virtual void clear()
{
clear(0);
}
public virtual void clear(int c)
{
screen.Clear(c);
}
public virtual void step() { }
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public void setPixelRaw(int x, int y, int c)
{
screen.SetPixel320x200x8((uint)x, (uint)y, (uint)c);
}
}
}
KERNEL:
using System;
using Sys = Cosmos.System;
using Display;
using Cosmos.Core;
using Cosmos.HAL;
using Cosmos.Common;
using Cosmos.Debug;
using Cosmos.IL2CPU;
namespace CosmosKernel3
{
public class Kernel : Sys.Kernel
{
protected override void BeforeRun()
{
Console.WriteLine("Booting VGADriver.");
try
{
var display = new DisplayDriver();
Console.WriteLine("ATTEMPTING");
display.init(); //init display
display.clear();
display.setPixel((int)40, 50, 60);
}
catch (Exception)
{
Console.WriteLine("Booting VGA failed. Booting into DOS mode.");
dosemergency();
}
}
protected override void Run()
{
boot();
while (true) ;
}
public static void boot()
{
}
public static void dosemergency()
{
Console.WriteLine("XENA DOS EMERGENCY MODE.");
Console.WriteLine("COMMANDS:");
Console.WriteLine("graphics -r (Graphics retry)");
String meow = Console.ReadLine();
if (meow == "graphics -r") ;
Console.WriteLine("Booting VGADriver.");
try
{
var display = new DisplayDriver();
display.init(); //init display
boot(); //boot
}
catch (Exception)
{
Console.WriteLine("Booting VGA failed. Booting into DOS mode.");
dosemergency();
}
}
}
}
SCREENSHOT:
Anyway, this has been happening for a while now and I cant seem to figure out why its doing this. Help!

I don't know if it's not too late, however this issue is popular in Cosmos, so future readers might find this answer.
Your code is correct. After talking with one of the devs he told me that they are aware of the issue and it happens because
current code [of Cosmos] uses delegates for pixelputting
If you wait 1-2 minutes, the screen will finally load.
edit:
I found a way to speed up this process a lot:
never call
Screen.clear()
function
Instead create the following function:
public void DrawFilledRectangle(uint x0, uint y0, int Width, int Height, int color)
{
for (uint i = 0; i < Width; i++)
{
for (uint h = 0; h < Height; h++)
{
setPixel((int)(x0 + i), (int)(y0 + h), color);
}
}
}
and replace
public virtual void clear(int c)
{
screen.Clear(c);
}
function
by:
public virtual void clear(int c)
{
//screen.Clear(c);
DrawFilledRectangle(0, 0, width, height, c);
}
Also replace init function by:
public void init()
{
screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8);
width = screen.PixelWidth;
height = screen.PixelHeight;
clear(0);
}
Which is much faster. Good luck in creating your OS :)

Related

C# Inheritance and Methods

I'm learning inheritance and I understand the code below.
namespace InheritanceApplication {
class Shape {
public void setWidth(int w) {
width = w;
}
public void setHeight(int h) {
height = h;
}
protected int width;
protected int height;
}
// Base class PaintCost
public interface PaintCost {
int getCost(int area);
}
// Derived class
class Rectangle : Shape, PaintCost {
public int getArea() {
return (width * height);
}
public int getCost(int area) {
return area * 70;
}
}
class RectangleTester {
static void Main(string[] args) {
Rectangle Rect = new Rectangle();
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
Console.WriteLine("Total area: {0}", Rect.getArea());
Console.WriteLine("Total paint cost: ${0}" , Rect.getCost(area));
Console.ReadKey();
}
}
}
However, why have they created the set height and set width functions. Would it not be better practice to simply just do this:
public int width {get;set;}
public int height {get;set;}
and then in the main class just do something like below:
rect.width = 5;
rect.height = 7;
Many thanks,
Amir
I'm sure others will provide different points, but here are my main 2 reasons for using gets/sets. If these don't apply for a given property, chances are I won't use getters/setters.
1 - Debugging
It makes it significantly easier to debug data propagation (how data gets passed around) if you can debug a setter that you're concerned about. You can easily throw in a Debug.Print call and debug the value being set if you're concerned it's being passed the wrong value. Or you could place break points and actually debug through the stack trace. For example:
class Shape {
public void setWidth(int w) {
if(w < 0)
Debug.Print("width is less than 0!");
width = w;
}
public void setHeight(int h) {
height = h;
}
protected int width;
protected int height;
}
2 - Value Change Actions
There may be better ways to achieve this, but I like being able to add simple logic to setters to ensure that any logic that needs to run when a value changes does so. For instance I may use the following:
public void SetWindowHeight(int newHeight)
{
if(WindowHeight == newHeight)
return;
WindowHeight = newHeight;
UpdateWindowDisplay();
}
public int GetWindowHeight()
{
return WindowHeight;
}
private int WindowHeight;
public void UpdateWindowDisplay()
{
Window.UpdateHeight(WindowHeight);
// Other window display logic
}
Although personally I prefer to use property gets/sets, but that's just my preference.
public int WindowHeight
{
get
{
return windowHeight;
}
set
{
if(windowHeight == value)
return;
windowHeight = value;
UpdateWindowDisplay();
}
}
private int windowHeight;
public void UpdateWindowDisplay()
{
Window.UpdateHeight(WindowHeight);
// Other window display logic
}

C# unable to move character in ASCII Console game

I have a C# project for school. I am unable to move my character in this ASCII console game. It has to be OO. After I run the code I get this:
After I press left or right I get
Can someone help me on this? Any help is appreciated.
program.cs:
class Program
{
static void Main(string[] args)
{
SuperConsole.Init(50, 44);
// create the game
Game game = new Game(30, 30);
//create objects
Entity spaceship = new Entity(1, 15, '#', SuperConsoleColor.Cyan);
// start the game loop
RunGameLoop(game);
}
protected static void RunGameLoop(Game game)
{
SuperConsole.BackgroundColor = SuperConsoleColor.DarkBlue;
SuperConsole.ForegroundColor = SuperConsoleColor.Gray;
int refreshRate = 20;
SuperConsole.CursorVisible = false;
SuperConsole.BackgroundColor = SuperConsoleColor.DarkBlue;
SuperConsole.ForegroundColor = SuperConsoleColor.Gray;
SuperConsole.Clear();
Reset(game);
game.Draw(0.0f);
SuperConsole.Flush();
/*
SuperConsole.SetCursorPosition(0, 0);*/
while (true)
{
while (SuperConsole.KeyAvailable)
{
ConsoleKeyInfo key = SuperConsole.ReadKey(true);
game.OnInput(key.Key);
}
System.Threading.Thread.Sleep(1000 / refreshRate);
Reset(game);
game.Draw(1.0f / (float)refreshRate);
SuperConsole.Flush();
}
}
protected static void Reset(Game game)
{
SuperConsole.BackgroundColor = SuperConsoleColor.Black;
SuperConsole.ForegroundColor = SuperConsoleColor.Black;
SuperConsole.SetCursorPosition(0, 0);
for (int y = 0; y < game.GetHeight(); ++y)
{
for (int x = 0; x < game.GetWidth(); ++x)
{
SuperConsole.Write(" ");
}
SuperConsole.WriteLine();
}
SuperConsole.SetCursorPosition(0, 0);
}
}
}
game.cs:
class Game : Entity
{
protected int width, height;
Entity spaceship = new Entity(1, 15, '#', SuperConsoleColor.Cyan);
public Game(int newWidth, int newHeight)
{
// set the size
width = newWidth;
height = newHeight;
// set the window
Console.WindowWidth = width+1;
Console.WindowHeight = height+1;
}
public int GetWidth()
{
return width;
}
public int GetHeight()
{
return height;
}
public void Draw(float dt)
{
SuperConsole.SetCursorPosition(spaceship.GetX(), spaceship.GetY());
SuperConsole.ForegroundColor = spaceship.GetColour();
SuperConsole.Write(spaceship.GetChar());
}
public void OnInput(ConsoleKey key)
{
int redo = 0;
ConsoleKey pressedKey = key;
do
{
Console.Clear();
switch (pressedKey)
{
case ConsoleKey.LeftArrow:
SuperConsole.SetCursorPosition(spaceship.GetX() - 1, spaceship.GetY());
break;
case ConsoleKey.UpArrow:
break;
case ConsoleKey.RightArrow:
SuperConsole.SetCursorPosition(spaceship.GetX()+1, spaceship.GetY());
break;
case ConsoleKey.DownArrow:
break;
}
} while (redo == 0);
}
}
}
entity.cs:
class Entity
{
protected int xPos;
protected int yPos;
protected char character;
protected SuperConsoleColor colour;
public Entity()
{
}
public Entity(int xPosNew, int yPosNew, char newCharacter, SuperConsoleColor newColour)
{
//define position
xPos = xPosNew;
yPos = yPosNew;
//define character
character = newCharacter;
//define colour
colour = newColour;
}
public char GetChar()
{
return character;
}
public int GetX()
{
return xPos;
}
public int GetY()
{
return yPos;
}
public SuperConsoleColor GetColour()
{
return colour;
}
}
}
I see two issues:
Within RunGameLoop(Game game) you should replace while (SuperConsole.KeyAvailable) with if (SuperConsole.KeyAvailable).
Within Game.OnInput(ConsoleKey) you change the cursor position instead of the spaceship position
Also try using breakpoints to Check if the code reaches Game.Draw() and check if the spaceship position and the cursor position are correct.
Also you should get a bit more into C#.
Instead of
public char GetChar()
{
return character;
}
private character;
.Net allows you to use Properties:
public char Character
{
get; private set;
}
or
public char Character
{
get { return character; }
}
private character = '#';
Hope this helps.
Apart from that: No offense, but this question isn't really what Stackoverflow is for. In future, please be more patient and try to googling debugging tips instead of letting Stackoverflow do the 'dirty work' for you.

NeuroSky Mindwave Music Visualizer with Unity

I'm working on a final project for school (art school not computer science) where I'd like to make a live visualizer from brainwaves using a NeuroSky Mindwave brain reader and Unity. Unfortunately the teacher has very limited knowledge of coding as well and has left me in a very bad position...
I've built a music visualizer following this tutorial:
https://www.youtube.com/watch?v=ELLANEFw5B8
And also found an example Unity project which can live read and display raw data from the brainwave reader:
https://github.com/tgraupmann/unity_neurosky
Where I'm stuck is in trying to change the input of my visualizer to be the raw brainwave data rather than music.
Is someone able to help me move forward with this project? I've already looked at NeuroSky's Unity integration page and emailed them with no success.
Any help will be greatly appreciated, thanks so much!
Audio Spectrum Visualizer Code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spectrum : MonoBehaviour {
// Use this for initialization
public GameObject prefab;
public int numberOfObjects = 20;
public float radius = 5f;
public GameObject[] cubes;
void Start()
{
for (int i = 0; i < numberOfObjects; i++)
{
float angle = i * Mathf.PI * 2 / numberOfObjects;
Vector3 pos = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Instantiate(prefab, pos, Quaternion.identity);
}
cubes = GameObject.FindGameObjectsWithTag ("cubes");
}
// Update is called once per frame
void Update () {
float[] spectrum = AudioListener.GetSpectrumData (1024, 0, FFTWindow.Hamming);
for(int i = 0; i < numberOfObjects; i++)
{
Vector3 previousScale = cubes[i].transform.localScale;
previousScale.y = Mathf.Lerp (previousScale.y, spectrum[i] * 40, Time.deltaTime * 30);
cubes[i].transform.localScale = previousScale;
}
}
}
ThinkGear Connector Controller Code
(as far as I know the file that causes the raw data to be displayed in Unity like the screenshot commented below)
using System;
using System.Threading;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using MindWave.LitJson;
using System.Net.Sockets;
using System.Text;
using System.IO;
namespace MindWave
{
public class TGCConnectionController : MonoBehaviour
{
private TcpClient client;
private Stream stream;
private byte[] buffer;
public delegate void UpdateIntValueDelegate(int value);
public delegate void UpdateFloatValueDelegate(float value);
public event UpdateIntValueDelegate UpdatePoorSignalEvent;
public event UpdateIntValueDelegate UpdateAttentionEvent;
public event UpdateIntValueDelegate UpdateMeditationEvent;
public event UpdateIntValueDelegate UpdateRawdataEvent;
public event UpdateIntValueDelegate UpdateBlinkEvent;
public event UpdateFloatValueDelegate UpdateDeltaEvent;
public event UpdateFloatValueDelegate UpdateThetaEvent;
public event UpdateFloatValueDelegate UpdateLowAlphaEvent;
public event UpdateFloatValueDelegate UpdateHighAlphaEvent;
public event UpdateFloatValueDelegate UpdateLowBetaEvent;
public event UpdateFloatValueDelegate UpdateHighBetaEvent;
public event UpdateFloatValueDelegate UpdateLowGammaEvent;
public event UpdateFloatValueDelegate UpdateHighGammaEvent;
private bool m_waitForExit = true;
private void Start()
{
ThreadStart ts = new ThreadStart(Connect);
Thread thread = new Thread(ts);
thread.Start();
}
public void Disconnect()
{
stream.Close();
}
public void Connect()
{
client = new TcpClient("127.0.0.1", 13854);
stream = client.GetStream();
buffer = new byte[1024];
byte[] myWriteBuffer = Encoding.ASCII.GetBytes(#"{""enableRawOutput"": true, ""format"": ""Json""}");
stream.Write(myWriteBuffer, 0, myWriteBuffer.Length);
while (m_waitForExit)
{
ParseData();
Thread.Sleep(100);
}
}
public class PowerData
{
public float delta = 0;
public float theta = 0;
public float lowAlpha = 0;
public float highAlpha = 0;
public float lowBeta = 0;
public float highBeta = 0;
public float lowGamma = 0;
public float highGamma = 0;
public PowerData()
{
}
}
public class SenseData
{
public int attention = 0;
public int meditation = 0;
public PowerData eegPower = null;
public SenseData()
{
}
}
public class PackatData
{
public string status = string.Empty;
public int poorSignalLevel = 0;
public int rawEeg = 0;
public int blinkStrength = 0;
public SenseData eSense = null;
public PackatData()
{
}
}
int GetObjectCount(String json)
{
int level = 0;
int count = 0;
for (int i = 0; i < json.Length; ++i)
{
if (json[i].Equals('{'))
{
if (level == 0)
{
++count;
}
++level;
}
if (json[i].Equals('}'))
{
--level;
}
}
return count;
}
private void ParseData()
{
if (stream.CanRead)
{
try
{
int bytesRead = stream.Read(buffer, 0, buffer.Length);
List<PackatData> packets = new List<PackatData>();
String packet = Encoding.ASCII.GetString(buffer, 0, bytesRead);
if (!string.IsNullOrEmpty(packet))
{
Debug.Log(packet);
if (packet.Contains("}"))
{
int count = GetObjectCount(packet);
if (count == 1)
{
PackatData data = JsonMapper.ToObject<PackatData>(packet);
packets.Add(data);
}
else if (count > 1)
{
PackatData[] data = JsonMapper.ToObject<PackatData[]>(packet);
for (int index = 0; index < data.Length; ++index)
{
packets.Add(data[index]);
}
}
}
}
foreach (PackatData data in packets)
{
if (null == data)
{
continue;
}
if (data.poorSignalLevel != 0)
{
Debug.Log("data.poorSignalLevel: " + data.poorSignalLevel);
if (null != UpdatePoorSignalEvent)
{
UpdatePoorSignalEvent.Invoke(data.poorSignalLevel);
}
if (null != data.eSense)
{
if (UpdateAttentionEvent != null)
{
UpdateAttentionEvent(data.eSense.attention);
}
if (UpdateMeditationEvent != null)
{
UpdateMeditationEvent(data.eSense.meditation);
}
if (null != data.eSense.eegPower)
{
if (UpdateDeltaEvent != null)
{
UpdateDeltaEvent(data.eSense.eegPower.delta);
}
if (UpdateThetaEvent != null)
{
UpdateThetaEvent(data.eSense.eegPower.theta);
}
if (UpdateLowAlphaEvent != null)
{
UpdateLowAlphaEvent(data.eSense.eegPower.lowAlpha);
}
if (UpdateHighAlphaEvent != null)
{
UpdateHighAlphaEvent(data.eSense.eegPower.highAlpha);
}
if (UpdateLowBetaEvent != null)
{
UpdateLowBetaEvent(data.eSense.eegPower.lowBeta);
}
if (UpdateHighBetaEvent != null)
{
UpdateHighBetaEvent(data.eSense.eegPower.highBeta);
}
if (UpdateLowGammaEvent != null)
{
UpdateLowGammaEvent(data.eSense.eegPower.lowGamma);
}
if (UpdateHighGammaEvent != null)
{
UpdateHighGammaEvent(data.eSense.eegPower.highGamma);
}
}
}
}
else if (data.rawEeg != 0)
{
if (null != UpdateRawdataEvent)
{
UpdateRawdataEvent(data.rawEeg);
}
}
else if (data.blinkStrength != 0)
{
if (null != UpdateRawdataEvent)
{
UpdateBlinkEvent(data.blinkStrength);
}
}
}
}
catch (IOException e)
{
Debug.Log("IOException " + e);
}
catch (System.Exception e)
{
Debug.Log("Exception " + e);
}
}
} // end ParseData
void OnDisable()
{
m_waitForExit = false;
Disconnect();
}
private void OnApplicationQuit()
{
m_waitForExit = false;
Disconnect();
}
}
}
I think you missed the signal processing natural of this problem. Brainwave (if it's Beta wave) has relatively low frequency range, which is about 15 Hz to 30 Hz. Music, on the other hand is audible tone, whose frequency range is between 20 Hz to 20,000 Hz.
I am not familiar with the implementation of this particular visualizer you mentioned here, but if it's implemented as what visualizer suppose to do, the brainwave should show only show some small activity (depends on the amplitude of the brainwave signal) in the lowest frequency range in the spectrum.
There is a potential hack to fix the problem. Usually a visualizer will use FFT to transform a time series signal to its frequency domain, during which it will determine the frequency range the operation is performed over. If you can locate the code in the visualizer and change the frequency range to, say 1 Hz to 100 Hz, you should see a proper frequency spectrum.

How to tell touchscreens from regular ones?

In case multiple screens are connected to a computer, I'd like to show an application on a touchscreen. By iterating over System.Windows.Forms.Screen.AllScreens I can get the WorkingArea in order to move the window. However, Screen doesn't provide a IsTouchscreen method.
On the other hand by iterating over all System.Windows.Input.Tablet.TabletDevices I am unable to find the corresponding Screen, because Screen.DeviceName doesn't match TabletDevice.Name.
So is there a way to somehow match a Screenwith a TabletDevice or is there another workaround I could use?
This information is available, the low-level COM interfaces that WPF uses are documented in this MSDN article. A disclaimer is however appropriate, Microsoft doesn't like you to use them. The interface documentation warns "Developers should not use this interface", otherwise without any obvious reason why that's good advice. If Microsoft really wants to prevent us from using it then it would be much simpler to just not document them.
And there's something funky going on with the ITablet2::GetMatchingScreenRect() function, the one you are looking for, the documentation for it missing. In itself a possible reason that this info is not exposed by WPF. So caution is necessary, you do need to test it thoroughly on the hardware you want to use it on. I don't have any to verify.
I wrote some code that uses these interfaces. Add a new class to your project and paste the code shown below. You need to add a reference to System.Drawing.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Text;
public enum TouchDeviceKind { Mouse, Pen, Touch }
public class TouchTabletCollection {
public TouchTabletCollection() {
Guid CLSID_TabletManager = new Guid("A5B020FD-E04B-4e67-B65A-E7DEED25B2CF");
var manager = (ITabletManager)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_TabletManager));
int count = 0;
manager.GetTabletCount(out count);
Count = count;
tablets = new List<TouchTablet>(count);
for (int index = 0; index < count; index++) {
tablets.Add(new TouchTablet(manager, index));
}
}
public int Count { get; private set; }
public TouchTablet this[int index] {
get { return tablets[index]; }
}
private List<TouchTablet> tablets;
}
public class TouchTablet {
internal TouchTablet(ITabletManager mgr, int index) {
ITablet itf;
mgr.GetTablet(index, out itf);
device1 = itf;
device2 = (ITablet2)itf;
device3 = (ITablet3)itf;
}
public bool IsMultiTouch {
get {
bool multi;
device3.IsMultiTouch(out multi);
return multi;
}
}
public TouchDeviceKind Kind {
get {
TouchDeviceKind kind;
device2.GetDeviceKind(out kind);
return kind;
}
}
public string Name {
get {
IntPtr pname;
device1.GetName(out pname);
return Marshal.PtrToStringUni(pname);
}
}
public Rectangle InputRectangle {
get {
RECT rc;
device1.GetMaxInputRect(out rc);
return Rectangle.FromLTRB(rc.Left, rc.Top, rc.Right, rc.Bottom);
}
}
public Rectangle ScreenRectangle {
get {
RECT rc;
device2.GetMatchingScreenRect(out rc);
return Rectangle.FromLTRB(rc.Left, rc.Top, rc.Right, rc.Bottom);
}
}
private ITablet device1;
private ITablet2 device2;
private ITablet3 device3;
}
// COM declarations
[ComImport, Guid("764DE8AA-1867-47C1-8F6A-122445ABD89A")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITabletManager {
void GetDefaultTablet(out ITablet table);
void GetTabletCount(out int count);
void GetTablet(int index, out ITablet tablet);
// rest omitted...
}
[ComImport, Guid("1CB2EFC3-ABC7-4172-8FCB-3BC9CB93E29F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITablet {
void Dummy1();
void Dummy2();
void GetName(out IntPtr pname);
void GetMaxInputRect(out RECT inputRect);
void GetHardwareCaps(out uint caps);
// rest omitted
}
[ComImport, Guid("C247F616-BBEB-406A-AED3-F75E656599AE")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITablet2 {
void GetDeviceKind(out TouchDeviceKind kind);
void GetMatchingScreenRect(out RECT rect);
}
[ComImport, Guid("AC0E3951-0A2F-448E-88D0-49DA0C453460")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface ITablet3 {
void IsMultiTouch(out bool multi);
void GetMaximumCursors(out int cursors);
}
internal struct RECT { public int Left, Top, Right, Bottom; }
A sample program that uses it:
using System;
class Program {
static void Main(string[] args) {
var tablets = new TouchTabletCollection();
for (int ix = 0; ix < tablets.Count; ++ix) {
Console.WriteLine("Found tablet {0} named {1}", ix + 1, tablets[ix].Name);
Console.WriteLine(" Type = {0}, Multi-touch supported = {1}", tablets[ix].Kind, tablets[ix].IsMultiTouch);
Console.WriteLine(" Input rectangle = {0}", tablets[ix].InputRectangle);
Console.WriteLine(" Screen rectangle = {0}", tablets[ix].ScreenRectangle);
}
Console.ReadLine();
}
}
Note that Windows 7 or higher is required. The output on my touch-ignorant laptop:
Found tablet 1 named \\.\DISPLAY1
Type = Mouse, Multi-touch supported = False
Input rectangle = {X=0,Y=0,Width=1440,Height=900}
Screen rectangle = {X=0,Y=0,Width=1440,Height=900}
have you tried.
public bool HasTouchInput()
{
foreach (TabletDevice tabletDevice in Tablet.TabletDevices)
{
//Only detect if it is a touch Screen
if(tabletDevice.Type == TabletDeviceType.Touch)
return true;
}
return false;
}
Try this Link
Or try This
var isTouchDevice = Tablet.TabletDevices.Cast<TabletDevice>().Any(dev => dev.Type == TabletDeviceType.Touch);
this is might also help

Is this efficient use of the is and as operator in a DrawableGameComponent?

I'm learning to use the as operator, and my goal was to create an option window (non windows form) that can:
Have options added to it (for flexibility, in case I want to use if statements to add menu items)
Be able to display text, textures, or a class (using the classes draw function)
Be controlled through the host GameState
I still haven't added the options for indicating an item is selected, my apologies for not posting a complete work. I also have not sorted the code into regions yet. Sorry again!
Is my code (particularly the draw function) properly using the is and as operators properly, from a performance and readability (non spaghetti code) standpoint?
public class OptionWindow : DrawableGameComponent
{
public Dictionary<int, Option> options;
int selectedOption;
bool windowLoops;
Rectangle drawRectangle;
int spacer;
int totalItemHeight;
SpriteFont sf;
SpriteBatch sb;
public Rectangle DrawRectangle
{
get { return drawRectangle; }
set { drawRectangle = value; }
}
public int SelectedOption
{
get { return selectedOption; }
set
{
if (windowLoops)
{
if (selectedOption >= options.Count())
selectedOption = 0;
if (selectedOption < 0)
selectedOption = options.Count() - 1;
}
else
{
if (selectedOption >= options.Count())
selectedOption = options.Count() - 1;
if (selectedOption < 0)
selectedOption = 0;
}
}
}
public OptionWindow(Game game, bool windowLoops, SpriteFont sf, Rectangle drawRectangle)
: base(game)
{
options = new Dictionary<int, Option>();
this.windowLoops = windowLoops;
this.sf = sf;
DrawRectangle = new Rectangle(drawRectangle.X, drawRectangle.Y, drawRectangle.Width, drawRectangle.Height);
}
public void Add(object option, bool selectable, bool defaultSelection, int height)
{
options.Add(options.Count(), new Option(selectable, option, height));
if (defaultSelection)
SelectedOption = options.Count() - 1;
UpdatePositions();
}
public void UpdatePositions()
{
UpdateTotalItemHeight();
if (options.Count() - 1 != 0)
spacer = (drawRectangle.Height - totalItemHeight) / (options.Count() - 1);
for (int i = 0; i < options.Count(); i++)
{
if (i == 0)
options[i].Position = new Vector2(drawRectangle.X, drawRectangle.Y);
else
{
options[i].Position = new Vector2(
drawRectangle.X,
options[i - 1].Position.Y + options[i - 1].Height + spacer);
}
}
}
public void UpdateTotalItemHeight()
{
totalItemHeight = 0;
for (int i = 0; i < options.Count(); i++)
{
totalItemHeight += options[i].Height;
}
}
protected override void LoadContent()
{
sb = new SpriteBatch(GraphicsDevice);
base.LoadContent();
}
public override void Draw(GameTime gameTime)
{
for (int i = 0; i < options.Count(); i++)
{
if (options[i].OptionObject is string)
sb.DrawString(sf, options[i].OptionObject as string, options[i].Position, Color.White);
if (options[i].OptionObject is Texture2D)
sb.Draw(options[i].OptionObject as Texture2D,
new Rectangle(
(int)options[i].Position.X,
(int)options[i].Position.Y,
options[i].Height,
(options[i].Height / (options[i].OptionObject as Texture2D).Height) * (options[i].OptionObject as Texture2D).Width),
Color.White);
if (options[i].OptionObject is DisplayObject)
(options[i].OptionObject as DisplayObject).Draw(gameTime);
}
base.Draw(gameTime);
}
}
public class Option
{
bool selectable;
object optionObject;
int height;
Vector2 position;
public bool Selectable
{
get { return selectable; }
set { selectable = value; }
}
public object OptionObject
{
get { return optionObject; }
set { optionObject = value; }
}
public int Height
{
get { return height; }
set { height = value; }
}
public Vector2 Position
{
get { return position; }
set { position = value; }
}
public Option(bool selectable, object option, int height)
{
Selectable = selectable;
OptionObject = option;
Height = height;
}
}
It is never adviseable to use is and then as. The usual way to go would be to either of the following:
just use is (if you just want to know the type without subsequent casting)
assign the result of as to a variable and check whether that variable is (not) null
The code analysis tool FxCop helps you find any spots in your code that use is and then as and warns you because of performance concerns.
Note however that a better approach altogether might be to declare your OptionObject property as some abstract class with a Draw method. You could then derive a subclass for strings, one for Texture2D instances and another one for DisplayObject instances and just call Draw in your OptionWindow.Draw method. This would leave the decision which actual drawing operations to execute up to built-in polymorphism features of the framework.

Categories

Resources