How can i make a better cursor

Aug 26, 2010 at 6:00 PM

I got this code :

 

                #region Mouse Data
                uint mx = (uint)Mouse2.X;
                uint my = (uint)Mouse2.Y;

                if (mx != x || my != y)
                {

                    if (Mouse2.Buttons == Mouse2.MouseState.Left) ;
                    else
                    {
                        VGAScreen.SetPixel320x200x8(x, y, oc);
                        x = mx;
                        y = my;
                        oc = VGAScreen.GetPixel320x200x8(x, y);
                    }
                }
                VGAScreen.SetPixel320x200x8(mx, my, 4);
                VGAScreen.SetPixel320x200x8(mx + 1, my + 1, 4); //doesn't work well
                #endregion

At the point "doesn't work well" i tried to make the cursor bigger, but with this the coursor paints the way  i go with my mouse.  What is wrong?

The mouse code (mouse2.cs):

using System;
using System.Collections.Generic;
using System.Text;
using Cosmos.Kernel;

namespace Cosmos.Hardware
{
    public static class Mouse2
    {
        public static int X, Y;
        public static MouseState Buttons;

        public static void Initialize()
        {

            //enable mouse
            WaitSignal();
            CPUBus.Write8(0x64, 0xA8);

            // enable interrupt
            WaitSignal();
            CPUBus.Write8(0x64, 0x20);
            WaitData();
            byte status = (byte)(CPUBus.Read8(0x60) | 2);
            WaitSignal();
            CPUBus.Write8(0x64, 0x60);
            WaitSignal();
            CPUBus.Write8(0x60, status);

            //default 
            Write(0xF6);
            Read();  //Acknowledge

            //Enable the mouse
            Write(0xF4);
            Read();  //Acknowledge

            Interrupts.AddIRQHandler(12, new Interrupts.InterruptDelegate(HandleMouse));

        }

        private static byte Read()
        {
            WaitData();
            return CPUBus.Read8(0x60);
        }

        private static void Write(byte b)
        {
            //Wait to be able to send a command
            WaitSignal();
            //Tell the mouse we are sending a command
            CPUBus.Write8(0x64, 0xD4);
            //Wait for the final part
            WaitSignal();
            //Finally write
            CPUBus.Write8(0x60, b);
        }

        private static void WaitData()
        {
            for (int i = 0; i < 1000 & ((CPUBus.Read8(0x64) & 1) == 1); i++)
                ;
        }

        private static void WaitSignal()
        {
            for (int i = 0; i < 1000 & ((CPUBus.Read8(0x64) & 2) != 0); i++)
                ;
        }

        public enum MouseState
        {
            None = 0,
            Left = 1,
            Right = 2,
            Middle = 4
        }

        private static byte mouse_cycle = 0;
        private static int[] mouse_byte = new int[4];

        public static void HandleMouse(ref Interrupts.InterruptContext context)
        {
            switch (mouse_cycle)
            {
                case 0:
                    mouse_byte[0] = CPUBus.Read8(0x60);

                    if ((mouse_byte[0] & 0x8) == 0x8)
                        mouse_cycle++;

                    break;
                case 1:
                    mouse_byte[1] = CPUBus.Read8(0x60);
                    mouse_cycle++;
                    break;
                case 2:
                    mouse_byte[2] = CPUBus.Read8(0x60);
                    mouse_cycle = 0;

                    if ((mouse_byte[0] & 0x10) == 0x10)
                        X -= mouse_byte[1] ^ 0xff;
                    else
                        X += mouse_byte[1];

                    if ((mouse_byte[0] & 0x20) == 0x20)
                        Y += mouse_byte[2] ^ 0xff;
                    else
                        Y -= mouse_byte[2];

                    if (X < 0)
                        X = 0;
                    else if (X > 319)
                        X = 319;

                    if (Y < 0)
                        Y = 0;
                    else if (Y > 199)
                        Y = 199;

                    Buttons = (MouseState)(mouse_byte[0] & 0x7);

                    break;
            }
        }
    }
}

Aug 27, 2010 at 4:41 AM

u can use vgascreen clear for an easy fix if u want smoother graphics like mine tho ull have to write alittle more code

Aug 27, 2010 at 8:18 AM

Now the cursor is perfect, but the screen flashes : (. I wahts the best thing to stop this. A loop?

Aug 27, 2010 at 10:03 AM

well i wont give u the code becasue u wont learn anything, but think abot it how did the single pixel mouse redraw what whas behind it

btw how would a loop fix this lol jw

Aug 27, 2010 at 10:18 AM

Mybe you can explain me the code before my brain explode xD

Aug 27, 2010 at 10:29 AM

LOOK AT UR ORIGINAL CODE!!! how did it redraw the pixels just use that code for each individual pixel eventually ull figure it out

Aug 27, 2010 at 12:24 PM
Edited Aug 27, 2010 at 12:29 PM

Now it works. But when i go with my mouse over my logo and other colored things, it starts to paint in this color

 

                #region Mouse Data
                uint mx = (uint)Mouse2.X;
                uint my = (uint)Mouse2.Y;

                if (mx != x || my != y)
                {

                    if (Mouse2.Buttons == Mouse2.MouseState.Left)
                    {
                        VGAScreen.SetPixel(mx, my, 1);
                    }
                    else
                    {
                        VGAScreen.SetPixel320x200x8(x, y, oc);
                        VGAScreen.SetPixel320x200x8(x + 1, y, oc);
                        VGAScreen.SetPixel320x200x8(x + 1, y, oc);
                        VGAScreen.SetPixel320x200x8(x + 2, y, oc);
                        VGAScreen.SetPixel320x200x8(x, y + 1, oc);
                        VGAScreen.SetPixel320x200x8(x, y + 2, oc);
                        VGAScreen.SetPixel320x200x8(x + 1, y + 1, oc);
                        VGAScreen.SetPixel320x200x8(x + 2, y + 2, oc);
                        VGAScreen.SetPixel320x200x8(x + 3, y + 3, oc);
                        x = mx;
                        y = my;
                        oc = VGAScreen.GetPixel320x200x8(x, y);
                    }
                }
                VGAScreen.SetPixel320x200x8(mx, my, 4);
                VGAScreen.SetPixel320x200x8(mx + 1, my, 4);
                VGAScreen.SetPixel320x200x8(mx + 1, my, 4);
                VGAScreen.SetPixel320x200x8(mx + 2, my, 4);
                VGAScreen.SetPixel320x200x8(mx, my + 1, 4);
                VGAScreen.SetPixel320x200x8(mx, my + 2, 4);
                VGAScreen.SetPixel320x200x8(mx + 1, my + 1, 4);
                VGAScreen.SetPixel320x200x8(mx + 2, my + 2, 4);
                VGAScreen.SetPixel320x200x8(mx + 3, my + 3, 4);
                #endregion

 

Aug 27, 2010 at 10:10 PM

hint - you need multiple oc variables such as one for each pixel

Aug 28, 2010 at 9:18 PM
Edited Aug 28, 2010 at 9:19 PM

Ok, now its perfect. But there is one more thing ... the cursor starts flashing above this code.

 

 

            for (uint i = 0; i < 120; i++)
            {
                for (uint j = 0; j < 15; j++)
                {
                    VGAScreen.SetPixel320x200x8(i, j, 3);
                }
            }

 

Aug 29, 2010 at 2:48 AM

is that code in a loop or is it drawn befor

Aug 29, 2010 at 9:40 AM

Actually, don't clear the screen or whatever, don't even bother to use multiple variables unless your os consists of only a few colours. Even so, if your OS is going to support resizing of windows and window positioning, don't even try. Instead, draw the background again, keeping track of which windows are open and re-drawing them too. The "Undraw mouse" is a good idea, keep it. Basically just re-draw the screen every time the mouse moves, much smoother than clearing the screen.

Aug 29, 2010 at 11:56 AM

I now made a code for a menu, but the problem is,how i undraw the menu? If there is a klick, it set the false to true and draw the menu window. If i klick again, it set it to false, The code is into the while loop, so clear will cause flashing. What do i have to do if i want to undraw the menu window?

 

                if (menuopen == false)
                {
                }
                else if (menuopen == true)
                {
                    drawWindow();
                }

Coordinator
Aug 29, 2010 at 12:15 PM

The fastest way are memory copy and merges. The graphics code in Cosmos is very primitive and only experimental at this point. Until we can work on it in a few months, you will have to take measures as you currently are to achieve what you want.

Aug 29, 2010 at 1:03 PM

Now it works. I put the if thing into the mouse code. But to clear the screen i draw with the background color over the menu xD It works, but it isn't smooth. Sometimes i have to klick 2-3 times if the menu disappear

Aug 29, 2010 at 2:15 PM

requimrar you dont redraw it that was part ofthe problem in the first place you undarw the mouse unless you ant your gui to flash every time you move it

but even so i dont have perfect mouse code and im constintly updating it to remove bugs

Coordinator
Aug 29, 2010 at 8:40 PM

Use double buffering. 

Aug 29, 2010 at 8:43 PM

theres double buffering implemented?? what code would i use

Coordinator
Aug 30, 2010 at 8:24 AM

It isn't implemented. Graphic support is very limited.

Feel free to read up on double buffering, implement it, and then submit a patch.